From 299ef94bcbc130e6e8e2621067777ab808274b76 Mon Sep 17 00:00:00 2001 From: jbw Date: Wed, 28 Jul 2021 05:44:25 +0000 Subject: [PATCH] [IMP] account: 'Import First Bill' Modal Improvement Improve the wizard 'import your first bill': usability + look & feel - Removed the PDF viewer interface which was ugly + useless in this context - Display an HTML preview instead which is dynamic - Current date - Company address depending on the Company - bill sequence depending on the date In the modal of upload, detect if there is no hosting domain @false > then remove this third option PR #75815 Task: 2581377 Related: odoo/upgrade#2806 Signed-off-by: Quentin De Paoli (qdp) --- addons/account/__manifest__.py | 1 + .../account/views/bill_preview_template.xml | 140 ++++++++++++++++++ .../wizard/account_tour_upload_bill.py | 94 ++++++++---- .../wizard/account_tour_upload_bill.xml | 10 +- 4 files changed, 215 insertions(+), 30 deletions(-) create mode 100644 addons/account/views/bill_preview_template.xml diff --git a/addons/account/__manifest__.py b/addons/account/__manifest__.py index 04ad17822b8..4129b9ce83f 100644 --- a/addons/account/__manifest__.py +++ b/addons/account/__manifest__.py @@ -77,6 +77,7 @@ You could use this simplified accounting in case you work with an (external) acc 'views/account_analytic_default_view.xml', 'wizard/account_tour_upload_bill.xml', 'wizard/accrued_orders.xml', + 'views/bill_preview_template.xml', ], 'demo': [ 'demo/account_demo.xml', diff --git a/addons/account/views/bill_preview_template.xml b/addons/account/views/bill_preview_template.xml new file mode 100644 index 00000000000..61025814b4b --- /dev/null +++ b/addons/account/views/bill_preview_template.xml @@ -0,0 +1,140 @@ + + + + + + \ No newline at end of file diff --git a/addons/account/wizard/account_tour_upload_bill.py b/addons/account/wizard/account_tour_upload_bill.py index 76c1eedf0c0..8ff164c7ba6 100644 --- a/addons/account/wizard/account_tour_upload_bill.py +++ b/addons/account/wizard/account_tour_upload_bill.py @@ -1,9 +1,10 @@ # -*- coding: utf-8 -*- # Part of Odoo. See LICENSE file for full copyright and licensing details. -from odoo import fields, models, api, _ -from odoo.modules.module import get_resource_path +from odoo import fields, models, _, Command import base64 +from datetime import timedelta + class AccountTourUploadBill(models.TransientModel): _name = 'account.tour.upload.bill' @@ -19,27 +20,40 @@ class AccountTourUploadBill(models.TransientModel): default="sample" ) - sample_bill_preview = fields.Binary( - readonly=True, - compute='_compute_sample_bill_image' + preview_invoice = fields.Html( + compute="_compute_preview_invoice", + string="Invoice Preview", + translate=True, ) + def _compute_preview_invoice(self): + invoice_date = fields.Date.today() - timedelta(days=12) + addr = [x for x in [ + self.env.company.street, + self.env.company.street2, + ' '.join([x for x in [self.env.company.state_id.name, self.env.company.zip] if x]), + self.env.company.country_id.name, + ] if x] + ref = 'INV/%s/0001' % invoice_date.strftime('%Y/%m') + html = self.env.ref('account.bill_preview')._render({ + 'company_name': self.env.company.name, + 'company_street_address': addr, + 'invoice_name': 'Invoice ' + ref, + 'invoice_ref': ref, + 'invoice_date': invoice_date, + 'invoice_due_date': invoice_date + timedelta(days=30), + }) + for record in self: + record.preview_invoice = html + def _selection_values(self): journal_alias = self.env['account.journal'] \ .search([('type', '=', 'purchase'), ('company_id', '=', self.env.company.id)], limit=1) - return [('sample', _('Try a sample vendor bill')), - ('upload', _('Upload your own bill')), - ('email', _('Or send a bill to %s@%s', journal_alias.alias_name, journal_alias.alias_domain))] - - def _compute_sample_bill_image(self): - """ Retrieve sample bill with facturx to speed up onboarding """ - try: - path = get_resource_path('account_edi_facturx', 'data/files', 'Invoice.pdf') - self.sample_bill_preview = base64.b64encode(open(path, 'rb').read()) if path else False - except (IOError, OSError): - self.sample_bill_preview = False - return + values = [('sample', _('Try a sample vendor bill')), ('upload', _('Upload your own bill'))] + if journal_alias.alias_name and journal_alias.alias_domain: + values.append(('email', _('Or send a bill to %s@%s', journal_alias.alias_name, journal_alias.alias_domain))) + return values def _action_list_view_bill(self, bill_ids=[]): context = dict(self._context) @@ -55,22 +69,52 @@ class AccountTourUploadBill(models.TransientModel): } def apply(self): - purchase_journal = self.env['account.journal'].search([('type', '=', 'purchase')], limit=1) + if self._context.get('active_model') == 'account.journal' and self._context.get('active_ids'): + purchase_journal = self.env['account.journal'].browse(self._context['active_ids']) + else: + purchase_journal = self.env['account.journal'].search([('type', '=', 'purchase')], limit=1) + if self.selection == 'upload': return purchase_journal.with_context(default_journal_id=purchase_journal.id, default_move_type='in_invoice').create_invoice_from_attachment(attachment_ids=self.attachment_ids.ids) elif self.selection == 'sample': + bodies = self.env['ir.actions.report']._prepare_html(self.preview_invoice)[0] + sample_pdf = self.env['ir.actions.report']._run_wkhtmltopdf(bodies) + + invoice_date = fields.Date.today() - timedelta(days=12) attachment = self.env['ir.attachment'].create({ 'type': 'binary', - 'name': 'INV/2020/0011.pdf', + 'name': 'INV-%s-0001.pdf' % invoice_date.strftime('%Y-%m'), 'res_model': 'mail.compose.message', - 'datas': self.sample_bill_preview, + 'datas': base64.encodebytes(sample_pdf), }) - bill_action = purchase_journal.with_context(default_journal_id=purchase_journal.id, default_move_type='in_invoice').create_invoice_from_attachment(attachment.ids) - bill = self.env['account.move'].browse(bill_action['res_id']) - bill.write({ - 'partner_id': self.env.ref('base.main_partner').id, - 'ref': 'INV/2020/0011' + partner = self.env['res.partner'].search([('name', '=', 'Deco Addict')], limit=1) + if not partner: + partner = self.env['res.partner'].create({ + 'name': 'Deco Addict', + 'is_company': True, }) + bill = self.env['account.move'].create({ + 'move_type': 'in_invoice', + 'partner_id': partner.id, + 'ref': 'INV/%s/0001' % invoice_date.strftime('%Y/%m'), + 'invoice_date': invoice_date, + 'invoice_date_due': invoice_date + timedelta(days=30), + 'journal_id': purchase_journal.id, + 'invoice_line_ids': [ + Command.create({ + 'name': "[FURN_8999] Three-Seat Sofa", + 'quantity': 5, + 'price_unit': 1500, + }), + Command.create({ + 'name': "[FURN_8220] Four Person Desk", + 'quantity': 5, + 'price_unit': 2350, + }) + ], + }) + bill.with_context(no_new_invoice=True).message_post(attachment_ids=[attachment.id]) + return self._action_list_view_bill(bill.ids) else: email_alias = '%s@%s' % (purchase_journal.alias_name, purchase_journal.alias_domain) diff --git a/addons/account/wizard/account_tour_upload_bill.xml b/addons/account/wizard/account_tour_upload_bill.xml index 53d33689643..cdece8f9463 100644 --- a/addons/account/wizard/account_tour_upload_bill.xml +++ b/addons/account/wizard/account_tour_upload_bill.xml @@ -9,14 +9,14 @@

With Odoo, you won't have to record bills manually

We process bills automatically so that you only have to validate them. Choose how you want to test our artificial intelligence engine:

- - + + - - + + - +