diff --git a/addons/account/models/account_move.py b/addons/account/models/account_move.py index e0f2c0f5b3..5f15f91662 100644 --- a/addons/account/models/account_move.py +++ b/addons/account/models/account_move.py @@ -151,7 +151,7 @@ class AccountMove(models.Model): ('in_refund', 'Vendor Credit Note'), ('out_receipt', 'Sales Receipt'), ('in_receipt', 'Purchase Receipt'), - ], string='Type', required=True, store=True, index=True, readonly=True, tracking=True, + ], string='Move Type', required=True, store=True, index=True, readonly=True, tracking=True, default="entry", change_default=True) type_name = fields.Char('Type Name', compute='_compute_type_name') to_check = fields.Boolean(string='To Check', default=False, diff --git a/addons/account_asset/models/account_invoice.py b/addons/account_asset/models/account_invoice.py index 6e5b649f10..639f88c6b3 100644 --- a/addons/account_asset/models/account_invoice.py +++ b/addons/account_asset/models/account_invoice.py @@ -90,11 +90,11 @@ class AccountInvoiceLine(models.Model): elif self.move_id.move_type == 'in_invoice' and self.asset_category_id: self.account_id = self.asset_category_id.account_asset_id.id - @api.onchange('uom_id') - def _onchange_uom_id(self): - result = super(AccountInvoiceLine, self)._onchange_uom_id() - self.onchange_asset_category_id() - return result + # @api.onchange('uom_id') + # def _onchange_uom_id(self): + # result = super(AccountInvoiceLine, self)._onchange_uom_id() + # self.onchange_asset_category_id() + # return result @api.onchange('product_id') def _onchange_product_id(self): diff --git a/addons/account_bank_statement_import/models/account_bank_statement_line.py b/addons/account_bank_statement_import/models/account_bank_statement_line.py index 159de4e74a..3e04bef8b6 100644 --- a/addons/account_bank_statement_import/models/account_bank_statement_line.py +++ b/addons/account_bank_statement_import/models/account_bank_statement_line.py @@ -14,7 +14,7 @@ class AccountBankStatementLine(models.Model): help="This technical field can be used at the statement line creation/import time in order to avoid the reconciliation" " process on it later on. The statement line will simply create a counterpart on this account") note = fields.Text(string='Notes') - journal_entry_ids = fields.One2many('account.move.line', 'statement_line_id', 'Journal Items', copy=False, + journal_entry_ids = fields.One2many('account.move.line', 'statement_line_id', 'Journals', copy=False, readonly=True) move_name = fields.Char(string='Journal Entry Name', readonly=True, default=False, copy=False, diff --git a/addons/account_bank_statement_import/models/account_move.py b/addons/account_bank_statement_import/models/account_move.py index b320aa45d9..acbac532bf 100644 --- a/addons/account_bank_statement_import/models/account_move.py +++ b/addons/account_bank_statement_import/models/account_move.py @@ -26,7 +26,7 @@ class AccountMove(models.Model): ('not_paid', 'Not Paid'), ('in_payment', 'In Payment'), ('paid', 'Paid')], - string='Payment', store=True, readonly=True, copy=False, tracking=True, + string='Status of Payment', store=True, readonly=True, copy=False, tracking=True, compute='_compute_amount') def action_open_reconcile(self): diff --git a/addons/account_bank_statement_import/models/account_payment.py b/addons/account_bank_statement_import/models/account_payment.py index 603be7e181..f1a25c6fad 100644 --- a/addons/account_bank_statement_import/models/account_payment.py +++ b/addons/account_bank_statement_import/models/account_payment.py @@ -8,7 +8,7 @@ from flectra.exceptions import UserError, ValidationError class AccountPayment(models.Model): _inherit = "account.payment" - payment_date = fields.Date(string='Date', default=fields.Date.context_today, required=True, readonly=True, + payment_date = fields.Date(string='Payment Date', default=fields.Date.context_today, required=True, readonly=True, states={'draft': [('readonly', False)]}, copy=False, tracking=True) communication = fields.Char(string='Memo', readonly=True, states={'draft': [('readonly', False)]}) move_line_ids = fields.One2many('account.move.line', 'payment_id', readonly=True, copy=False) diff --git a/addons/accounting_pdf_reports/wizards/account_report.py b/addons/accounting_pdf_reports/wizards/account_report.py index cdf496b690..3500bee95c 100644 --- a/addons/accounting_pdf_reports/wizards/account_report.py +++ b/addons/accounting_pdf_reports/wizards/account_report.py @@ -20,8 +20,8 @@ class AccountingReport(models.TransientModel): account_report_id = fields.Many2one('account.financial.report', string='Account Reports', required=True, default=_get_account_report) label_filter = fields.Char(string='Column Label', help="This label will be displayed on report to show the balance computed for the given comparison filter.") filter_cmp = fields.Selection([('filter_no', 'No Filters'), ('filter_date', 'Date')], string='Filter by', required=True, default='filter_no') - date_from_cmp = fields.Date(string='Start Date') - date_to_cmp = fields.Date(string='End Date') + date_from_cmp = fields.Date(string='From Date') + date_to_cmp = fields.Date(string='To Date') debit_credit = fields.Boolean(string='Display Debit/Credit Columns', help="This option allows you to get more details about the way your balances are computed. Because it is space consuming, we do not allow to use it while doing a comparison.") def _build_comparison_context(self, data): diff --git a/addons/digest/models/res_users.py b/addons/digest/models/res_users.py index 2e17162ca6..93dd1ea125 100644 --- a/addons/digest/models/res_users.py +++ b/addons/digest/models/res_users.py @@ -13,6 +13,6 @@ class ResUsers(models.Model): default_digest_emails = self.env['ir.config_parameter'].sudo().get_param('digest.default_digest_emails') default_digest_id = self.env['ir.config_parameter'].sudo().get_param('digest.default_digest_id') if default_digest_emails and default_digest_id: - digest = self.env['digest.digest'].sudo().browse(int(default_digest_id)) + digest = self.env['digest.digest'].sudo().browse(int(default_digest_id)).exists() digest.user_ids |= users.filtered_domain([('share', '=', False)]) return users diff --git a/addons/dms/tests/test_portal.py b/addons/dms/tests/test_portal.py index 9d8da0f31d..11f2bc9586 100644 --- a/addons/dms/tests/test_portal.py +++ b/addons/dms/tests/test_portal.py @@ -6,7 +6,7 @@ import flectra.tests @flectra.tests.tagged("post_install", "-at_install") class TestDmsPortal(flectra.tests.HttpCase): def test_tour(self): - self.phantom_js( + self.start_tour( "/", "flectra.__DEBUG__.services['web_tour.tour'].run('dms_portal_tour')", "flectra.__DEBUG__.services['web_tour.tour'].tours.dms_portal_tour.ready", diff --git a/addons/event_sale/models/sale_order.py b/addons/event_sale/models/sale_order.py index e4f0a5e686..49081a7fa8 100644 --- a/addons/event_sale/models/sale_order.py +++ b/addons/event_sale/models/sale_order.py @@ -47,6 +47,10 @@ class SaleOrder(models.Model): for sale_order in self: sale_order.attendee_count = attendee_count_data.get(sale_order.id, 0) + def unlink(self): + self.order_line._unlink_associated_registrations() + return super(SaleOrder, self).unlink() + class SaleOrderLine(models.Model): @@ -120,6 +124,13 @@ class SaleOrderLine(models.Model): # we call this to force update the default name self.product_id_change() + def unlink(self): + self._unlink_associated_registrations() + return super(SaleOrderLine, self).unlink() + + def _unlink_associated_registrations(self): + self.env['event.registration'].search([('sale_order_line_id', 'in', self.ids)]).unlink() + def get_sale_order_line_multiline_description_sale(self, product): """ We override this method because we decided that: The default description of a sales order line containing a ticket must be different than the default description when no ticket is present. diff --git a/addons/event_sale/tests/test_event_sale.py b/addons/event_sale/tests/test_event_sale.py index e0a7e14b49..2d7eac457e 100644 --- a/addons/event_sale/tests/test_event_sale.py +++ b/addons/event_sale/tests/test_event_sale.py @@ -2,6 +2,8 @@ # Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. from flectra.addons.event_sale.tests.common import TestEventSaleCommon +from flectra.addons.mail.tests.common import mail_new_test_user + from flectra.tests import tagged from flectra.tests.common import users @@ -13,20 +15,59 @@ class TestEventSale(TestEventSaleCommon): def setUpClass(cls): super(TestEventSale, cls).setUpClass() + product = cls.env['product.product'].create({ + 'name': 'Event', + 'type': 'service', + 'event_ok': True, + }) + + cls.user_salesperson = mail_new_test_user(cls.env, login='user_salesman', groups='sales_team.group_sale_salesman') + + cls.ticket = cls.env['event.event.ticket'].create({ + 'name': 'First Ticket', + 'product_id': cls.event_product.id, + 'seats_max': 30, + 'event_id': cls.event_0.id, + }) + cls.event_0.write({ 'event_ticket_ids': [ - (5, 0), + (6, 0, cls.ticket.ids), (0, 0, { - 'name': 'First Ticket', - 'product_id': cls.event_product.id, - 'seats_max': 30, - }), (0, 0, { 'name': 'Second Ticket', 'product_id': cls.event_product.id, }) ], }) + cls.sale_order = cls.env['sale.order'].create({ + 'partner_id': cls.env.ref('base.res_partner_2').id, + 'note': 'Invoice after delivery', + 'payment_term_id': cls.env.ref('account.account_payment_term_end_following_month').id + }) + + # In the sales order I add some sales order lines. i choose event product + cls.env['sale.order.line'].create({ + 'product_id': product.id, + 'price_unit': 190.50, + 'product_uom': cls.env.ref('uom.product_uom_unit').id, + 'product_uom_qty': 1.0, + 'order_id': cls.sale_order.id, + 'name': 'sales order line', + 'event_id': cls.event_0.id, + 'event_ticket_id': cls.ticket.id, + }) + + cls.register_person = cls.env['registration.editor'].create({ + 'sale_order_id': cls.sale_order.id, + 'event_registration_ids': [(0, 0, { + 'event_id': cls.event_0.id, + 'name': 'Administrator', + 'email': 'abc@example.com', + 'sale_order_line_id': cls.sale_order.order_line.id, + })], + }) + # make a SO for a customer, selling some tickets cls.customer_so = cls.env['sale.order'].with_user(cls.user_sales_salesman).create({ 'partner_id': cls.event_customer.id, @@ -209,3 +250,23 @@ class TestEventSale(TestEventSaleCommon): }) sol.product_id_change() self.assertEqual(so.amount_total, 660.0, "Ticket is $1000 but the event product is on a pricelist 10 -> 6. So, $600 + a 10% tax.") + + @users('user_salesman') + def test_unlink_so(self): + """ This test ensures that when deleting a sale order, if the latter is linked to an event registration, + the number of expected seats will be correctly updated """ + event = self.env['event.event'].browse(self.event_0.ids) + self.register_person.action_make_registration() + self.assertEqual(event.seats_expected, 1) + self.sale_order.unlink() + self.assertEqual(event.seats_expected, 0) + + @users('user_salesman') + def test_unlink_soline(self): + """ This test ensures that when deleting a sale order line, if the latter is linked to an event registration, + the number of expected seats will be correctly updated """ + event = self.env['event.event'].browse(self.event_0.ids) + self.register_person.action_make_registration() + self.assertEqual(event.seats_expected, 1) + self.sale_order.order_line.unlink() + self.assertEqual(event.seats_expected, 0) diff --git a/addons/event_sale/wizard/event_edit_registration.py b/addons/event_sale/wizard/event_edit_registration.py index 78905b70e1..a0627f969e 100644 --- a/addons/event_sale/wizard/event_edit_registration.py +++ b/addons/event_sale/wizard/event_edit_registration.py @@ -7,7 +7,7 @@ class RegistrationEditor(models.TransientModel): _name = "registration.editor" _description = 'Edit Attendee Details on Sales Confirmation' - sale_order_id = fields.Many2one('sale.order', 'Sales Order', required=True) + sale_order_id = fields.Many2one('sale.order', 'Sales Order', required=True, ondelete='cascade') event_registration_ids = fields.One2many('registration.editor.line', 'editor_id', string='Registrations to Edit') @api.model diff --git a/addons/l10n_eu_service/wizard/wizard.py b/addons/l10n_eu_service/wizard/wizard.py index 0fd3f14c48..f68e5c4dc1 100644 --- a/addons/l10n_eu_service/wizard/wizard.py +++ b/addons/l10n_eu_service/wizard/wizard.py @@ -2,7 +2,7 @@ # Part of Odoo, Flectra. See LICENSE file for full copyright and licensing details. from flectra import api, fields, models, _ -from flectra.exceptions import Warning +from flectra.exceptions import UserError, Warning class l10n_eu_service(models.TransientModel): @@ -70,6 +70,12 @@ class l10n_eu_service(models.TransientModel): 'res.country', 'l10n_eu_service_country_rel_todo', default=_default_todo_country_ids, string='EU Customers From', required=True) + @api.model + def load_views(self, views, options=None): + # This wizard is outdated; it shouldn't be used anymore. Users might still be able to open it using the + # link in the settings if they didn't update the module. If they try, we tell them. + raise UserError(_("Starting July 1st 2021, OSS regulation has replaced MOSS. Please first upgrade 'l10n_eu_service' module in the Apps menu, then go back to this setting and click on 'Refresh tax mapping'.")) + def _get_repartition_line_copy_values(self, original_rep_lines): return [(0, 0, { 'factor_percent': line.factor_percent, diff --git a/addons/portal_rating/static/src/xml/portal_chatter.xml b/addons/portal_rating/static/src/xml/portal_chatter.xml index adb0174b2d..93d0122c2b 100644 --- a/addons/portal_rating/static/src/xml/portal_chatter.xml +++ b/addons/portal_rating/static/src/xml/portal_chatter.xml @@ -85,7 +85,7 @@
Published on