def test_create_subtask(self): with self.sudo('employee-a'): with self.allow_companies([self.company_a.id, self.company_b.id]): # create subtask, set parent; the onchange will set the correct company and subtask project with Form(self.env['project.task'].with_context( {'tracking_disable': True})) as task_form: task_form.name = 'Test Subtask in company B' task_form.parent_id = self.task_1 task_form.project_id = self.project_company_b task = task_form.save() self.assertEqual( task.company_id, self.project_company_b.company_id, "The company of the subtask should be the one from its project, and not from its parent." ) # set parent on existing orphan task; the onchange will set the correct company and subtask project self.task_2.write({'project_id': False}) with Form(self.task_2) as task_form: task_form.name = 'Test Task 2 becomes child of Task 1 (other company)' task_form.parent_id = self.task_1 task = task_form.save() self.assertEqual( task.company_id, task.project_id.company_id, "The company of the orphan subtask should be the one from its project." )
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 test_out_refund_line_onchange_sequence_number_1(self): self.assertRecordValues( self.invoice, [{ 'invoice_sequence_number_next': '0001', 'invoice_sequence_number_next_prefix': 'RINV/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': 'RINV/2019/', }]) self.invoice.post() self.assertRecordValues(self.invoice, [{'name': 'RINV/2019/0042'}]) invoice_copy = self.invoice.copy() invoice_copy.post() self.assertRecordValues(invoice_copy, [{'name': 'RINV/2019/0043'}])
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_set_multiple_lot_name_01(self): """ Sets five SN in one time in stock move view form, then checks move has five new move lines with the right `lot_name`. """ nbre_of_lines = 10 move = self.get_new_move(nbre_of_lines) # We must begin with a move with 10 move lines. self.assertEqual(len(move.move_line_ids), nbre_of_lines) value_list = [ 'abc-235', 'abc-237', 'abc-238', 'abc-282', 'abc-301', ] values = '\n'.join(value_list) move_form = Form(move, view='stock.view_stock_move_nosuggest_operations') with move_form.move_line_nosuggest_ids.new() as line: line.lot_name = values move = move_form.save() # After we set multiple SN, we must have now 15 move lines. self.assertEqual(len(move.move_line_ids), nbre_of_lines + len(value_list)) # Then we look each SN name is correct. for move_line in move.move_line_nosuggest_ids: self.assertEqual(move_line.lot_name, value_list.pop(0)) for move_line in (move.move_line_ids - move.move_line_nosuggest_ids): self.assertEqual(move_line.lot_name, False)
def test_cross_subtask_project(self): # set up default subtask project self.project_company_a.write( {'subtask_project_id': self.project_company_b.id}) with self.sudo('employee-a'): with self.allow_companies([self.company_a.id, self.company_b.id]): with Form(self.env['project.task'].with_context( {'tracking_disable': True})) as task_form: task_form.name = 'Test Subtask in company B' task_form.parent_id = self.task_1 task = task_form.save() self.assertEqual( task.project_id, self.task_1.project_id.subtask_project_id, "The default project of a subtask should be the default subtask project of the project from the mother task" ) self.assertEqual( task.company_id, task.project_id.subtask_project_id.company_id, "The company of the orphan subtask should be the one from its project." ) with self.sudo('employee-a'): with self.assertRaises(AccessError): with Form(task) as task_form: task_form.name = "Testing changing name in a company I can not read/write"
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_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_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_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 init_invoice(cls, move_type): move_form = Form( cls.env['account.move'].with_context(default_type=move_type)) move_form.invoice_date = fields.Date.from_string('2019-01-01') move_form.partner_id = cls.partner_a with move_form.invoice_line_ids.new() as line_form: line_form.product_id = cls.product_a with move_form.invoice_line_ids.new() as line_form: line_form.product_id = cls.product_b return move_form.save()
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_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_readonly(self): """ Checks that fields with readonly modifiers (marked as readonly or computed w/o set) raise an error when set. """ f = Form(self.env['test_testing_utilities.readonly']) with self.assertRaises(AssertionError): f.f1 = '5' with self.assertRaises(AssertionError): f.f2 = 42
def test_o2m_default(self): """ Tests that default_get can return defaults for the o2m """ f = Form(self.env['test_testing_utilities.default']) with f.subs.edit(index=0) as s: self.assertEqual(s.v, 5) self.assertEqual(s.value, False) r = f.save() self.assertEqual([get(s) for s in r.subs], [("5", 0, 5)])
def _init_payment(cls, payment_type, partner_type=None): payment_form = Form(cls.env['account.payment']) payment_form.journal_id = cls.bank_journal payment_form.payment_date = fields.Date.from_string('2019-01-01') payment_form.amount = 100 if payment_type == 'transfer': payment_form.destination_journal_id = cls.cash_journal else: payment_form.partner_type = partner_type payment_form.partner_id = cls.partner_a payment_form.payment_type = payment_type return payment_form.save()
def test_o2m_widget(self): create = self.env['test_testing_utilities.sub'].create a, b, c = create({'v': 1}), create({'v': 2}), create({'v': 3}) f = Form(self.env['test_testing_utilities.parent'], view='test_testing_utilities.o2m_widget_m2m') f.subs.add(a) f.subs.add(b) f.subs.add(c) r = f.save() self.assertEqual(r.subs, a | b | c)
def test_2weeks_calendar(self): calendar = self.env['resource.calendar'].create({ 'name': 'auto next day', 'two_weeks_calendar': True, 'attendance_ids': [(5, 0, 0), (0, 0, { 'name': 'monday morning odd week', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning', 'dayofweek': '0', 'week_type': '0', }), (0, 0, { 'name': 'monday morning even week', 'hour_from': 10, 'hour_to': 12, 'day_period': 'morning', 'dayofweek': '0', 'week_type': '1', })] }) employee = self.employee_emp employee.resource_calendar_id = calendar with Form(self.env['hr.leave']) as leave_form: leave_form.employee_id = employee leave_form.holiday_status_id = self.leave_type # even week, works 2 hours leave_form.request_date_from = date(2019, 9, 2) leave_form.request_date_to = date(2019, 9, 2) leave_form.request_unit_half = True leave_form.request_date_from_period = 'am' self.assertEqual(leave_form.number_of_days_display, 1) self.assertEqual(leave_form.number_of_hours_display, 2) self.assertEqual(leave_form.date_from, datetime(2019, 9, 2, 8, 0, 0)) self.assertEqual(leave_form.date_to, datetime(2019, 9, 2, 10, 0, 0)) with Form(self.env['hr.leave']) as leave_form: leave_form.employee_id = employee leave_form.holiday_status_id = self.leave_type # odd week, works 4 hours leave_form.request_date_from = date(2019, 9, 9) leave_form.request_date_to = date(2019, 9, 9) leave_form.request_unit_half = True leave_form.request_date_from_period = 'am' self.assertEqual(leave_form.number_of_days_display, 1) self.assertEqual(leave_form.number_of_hours_display, 4) self.assertEqual(leave_form.date_from, datetime(2019, 9, 9, 6, 0, 0)) self.assertEqual(leave_form.date_to, datetime(2019, 9, 9, 10, 0, 0))
def test_readonly_save(self): """ Should not save readonly fields unless they're force_save """ f = Form(self.env['test_testing_utilities.a'], view='test_testing_utilities.non_normalized_attrs') f.f1 = '1' f.f2 = 987 self.assertEqual(f.f5, 987) self.assertEqual(f.f6, 987) r = f.save() self.assertEqual(r.f5, 0) self.assertEqual(r.f6, 987)
def test_add(self): Sub = self.env['test_testing_utilities.sub2'] f = Form(self.env['test_testing_utilities.e']) r1 = Sub.create({'name': "Item"}) r2 = Sub.create({'name': "Item2"}) f.m2m.add(r1) f.m2m.add(r2) r = f.save() self.assertEqual(r.m2m, r1 | r2)
def test_o2m_inline(self): """ Tests the o2m proxy when the list and form views are provided inline rather than fetched separately """ f = Form(self.env['test_testing_utilities.parent'], view='test_testing_utilities.o2m_parent_inline') with f.subs.new() as s: s.value = 42 r = f.save() self.assertEqual([get(s) for s in r.subs], [("0", 42, 0)], "should not have set v (and thus not name)")
def test_remove_by_index(self): Sub = self.env['test_testing_utilities.sub2'] f = Form(self.env['test_testing_utilities.e']) r1 = Sub.create({'name': "Item"}) r2 = Sub.create({'name': "Item2"}) f.m2m.add(r1) f.m2m.add(r2) f.m2m.remove(index=0) r = f.save() self.assertEqual(r.m2m, r2)
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 _create_invoice_line(self, amount, partner, type): ''' Create an invoice on the fly.''' invoice_form = Form(self.env['account.move'].with_context(default_type=type)) invoice_form.invoice_date = fields.Date.from_string('2019-09-01') invoice_form.partner_id = partner with invoice_form.invoice_line_ids.new() as invoice_line_form: invoice_line_form.name = 'xxxx' invoice_line_form.quantity = 1 invoice_line_form.price_unit = amount invoice_line_form.tax_ids.clear() invoice = invoice_form.save() invoice.post() lines = invoice.line_ids return lines.filtered(lambda l: l.account_id.user_type_id.type in ('receivable', 'payable'))
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 test_attendance_previous_day(self): calendar = self.env['resource.calendar'].create({ 'name': 'auto next day', 'attendance_ids': [(5, 0, 0), (0, 0, { 'name': 'monday morning', 'hour_from': 8, 'hour_to': 12, 'day_period': 'morning', 'dayofweek': '0', })] }) employee = self.employee_emp employee.resource_calendar_id = calendar with Form(self.env['hr.leave']) as leave_form: leave_form.employee_id = employee leave_form.holiday_status_id = self.leave_type leave_form.request_date_from = date(2019, 9, 3) leave_form.request_date_to = date(2019, 9, 3) leave_form.request_unit_half = True leave_form.request_date_from_period = 'am' self.assertEqual(leave_form.number_of_days_display, 0) self.assertEqual(leave_form.number_of_hours_display, 0) self.assertEqual(leave_form.date_from, datetime(2019, 9, 3, 6, 0, 0)) self.assertEqual(leave_form.date_to, datetime(2019, 9, 3, 10, 0, 0))
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_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_m2m_changed(self): Sub = self.env['test_testing_utilities.sub2'] a = Sub.create({'name': 'a'}) b = Sub.create({'name': 'b'}) c = Sub.create({'name': 'c'}) d = Sub.create({'name': 'd'}) f = Form(self.env['test_testing_utilities.f']) # check default_get self.assertEqual(f.m2m[:], a | b) f.m2o = c self.assertEqual(f.m2m[:], a | b | c) f.m2o = d self.assertEqual(f.m2m[:], a | b | c | d)
def test_m2o(self): Sub = self.env['test_testing_utilities.m2o'] a = Sub.create({'name': 'a'}) b = Sub.create({'name': 'b'}) c = Sub.create({'name': 'c'}) r = self.env['test_testing_utilities.d'].create({ 'f': c.id, 'f2': "OK", }) with Form(r) as f: # no default/onchange should have run so loading an incoherent # record should still be incoherent self.assertEqual(f.f, c) self.assertEqual(f.f2, 'OK') f.f2 = "b" self.assertEqual(f.f, b) f.f2 = "Whoops" self.assertEqual(f.f, Sub) f.f2 = "a" self.assertEqual(f.f, a) self.assertEqual(r.f2, "a") self.assertEqual(r.f, a)