diff --git a/__manifest__.py b/__manifest__.py index 86f6a3e0deba847ec14acbe1db6ee4fe6413bec8..17fe7214167d667935b781d1a78de9bd9da7a53e 100644 --- a/__manifest__.py +++ b/__manifest__.py @@ -27,6 +27,10 @@ 'views/sale_view.xml', 'views/account_invoice_view.xml', 'data/res_partner_data.xml', + 'views/report_templates.xml', + 'data/report_layout.xml', + 'report/report_sale.xml', + 'report/report_account.xml' ], } \ No newline at end of file diff --git a/data/report_layout.xml b/data/report_layout.xml new file mode 100644 index 0000000000000000000000000000000000000000..f27c1e22b1a8f31832ee0ce222b5b1e28ca1be7b --- /dev/null +++ b/data/report_layout.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <data> + + <record id="report_layout_boxed" model="report.layout"> + <field name="view_id" ref="autrement_dit_partner.autrement_external_layout_boxed"/> + <field name="image">/web/static/img/preview_boxed.png</field> + <field name="pdf">/web/static/pdf/preview_boxed.pdf</field> + </record> + </data> +</odoo> \ No newline at end of file diff --git a/models/account_invoice.py b/models/account_invoice.py index 1aa374545805f13ea58379b82ee3c692e6439121..c0b00c8f8b906ad83ed569445582a8d0307bad3c 100644 --- a/models/account_invoice.py +++ b/models/account_invoice.py @@ -6,4 +6,12 @@ from odoo import models, fields, api class AccountInvoice(models.Model): _inherit = "account.invoice" - beneficiaire_id = fields.Many2one('res.partner', string='Bénéficiaire',states={'draft': [('readonly', False)]}, domain=[('beneficiaire', '=', True)]) \ No newline at end of file + beneficiaire_id = fields.Many2one('res.partner', string='Bénéficiaire',states={'draft': [('readonly', False)]}, domain=[('beneficiaire', '=', True)]) + partner_is_beneficiaire = fields.Boolean('Est un Bénéficiaire') + + @api.onchange('partner_id') + def onchange_partner_id_benef(self): + if self.partner_id.beneficiaire == True: + self.partner_is_beneficiaire = True + else: + self.partner_is_beneficiaire = False diff --git a/models/sale.py b/models/sale.py index 7e7b0ffccaa999df6743fa8b7ef091572b5b4c27..1b8c5565518a17a77e8e0b3c644272a29ec5e66b 100644 --- a/models/sale.py +++ b/models/sale.py @@ -7,10 +7,18 @@ class AutreSaleOrder(models.Model): _inherit = "sale.order" beneficiaire_id = fields.Many2one('res.partner', string='Bénéficiaire', states={'draft': [('readonly', False)], 'sent': [('readonly', False)], 'sale': [('readonly', False)]}, domain=[('beneficiaire', '=', True)]) + partner_is_beneficiaire = fields.Boolean('Est un Bénéficiaire') @api.multi def _prepare_invoice(self): invoice_vals = super(AutreSaleOrder, self)._prepare_invoice() if self.beneficiaire_id: invoice_vals['beneficiaire_id'] = self.beneficiaire_id.id - return invoice_vals \ No newline at end of file + return invoice_vals + + @api.onchange('partner_id') + def onchange_partner_id_benef(self): + if self.partner_id.beneficiaire == True: + self.partner_is_beneficiaire = True + else: + self.partner_is_beneficiaire = False diff --git a/report/report_account.xml b/report/report_account.xml new file mode 100644 index 0000000000000000000000000000000000000000..0fcf1a8946c78fdd824b7fac6bb2515768ad2df7 --- /dev/null +++ b/report/report_account.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <template id="autrement_report_invoice_document" inherit_id="account.report_invoice_document"> + <xpath expr="//div[@class='page']" position="before"> + <t t-if="o.beneficiaire_id"> + <div name="information_block" class="col-6 mb32"> + <strong>Bénéficiaire:</strong><br/> + <t t-if="o.beneficiaire_id.name"><span class="bene-name" t-field="o.beneficiaire_id.name"/></t><br/> + <t t-if="o.beneficiaire_id.street"><span t-field="o.beneficiaire_id.street"/></t><br/> + <t t-if="o.beneficiaire_id.street2"><span t-field="o.beneficiaire_id.street2"/><br/></t> + <t t-if="o.beneficiaire_id.zip"><span t-field="o.beneficiaire_id.zip"/></t> + <t t-if="o.beneficiaire_id.city"><span t-field="o.beneficiaire_id.city"/></t><br/> + <t t-if="o.beneficiaire_id.phone"><span t-field="o.beneficiaire_id.phone"/></t> + </div> + </t> + </xpath> + + </template> + + +</odoo> diff --git a/report/report_sale.xml b/report/report_sale.xml new file mode 100644 index 0000000000000000000000000000000000000000..02b3c7ec3aba1ae587d3f7b459631f479d463498 --- /dev/null +++ b/report/report_sale.xml @@ -0,0 +1,204 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <template id="autrement_report_saleorder_document" inherit_id="sale.report_saleorder_document"> + <xpath expr="//div[@class='page']" position="before"> + <t t-if="doc.beneficiaire_id"> + <div name="information_block" class="col-6 mb32"> + <strong>Bénéficiaire:</strong><br/> + <t t-if="doc.beneficiaire_id.name"><span class="bene-name" t-field="doc.beneficiaire_id.name"/></t><br/> + <t t-if="doc.beneficiaire_id.street"><span t-field="doc.beneficiaire_id.street"/></t><br/> + <t t-if="doc.beneficiaire_id.street2"><span t-field="doc.beneficiaire_id.street2"/><br/></t> + <t t-if="doc.beneficiaire_id.zip"><span t-field="doc.beneficiaire_id.zip"/></t> + <t t-if="doc.beneficiaire_id.city"><span t-field="doc.beneficiaire_id.city"/></t><br/> + <t t-if="doc.beneficiaire_id.phone"><span t-field="doc.beneficiaire_id.phone"/></t> + </div> + </t> + </xpath> + + <xpath expr="//div[@class='page']" position="replace"> + <div class="page"> + <div class="oe_structure"/> + + <h2> + <t t-if="not (env.context.get('proforma', False) or is_pro_forma)"> + <span t-if="doc.state not in ['draft','sent']">Commande N° </span> + <span t-if="doc.state in ['draft','sent']">Devis N° </span> + </t> + <t t-if="env.context.get('proforma', False) or is_pro_forma"> + <span>Facture Pro-Forma N° </span> + </t> + <span t-field="doc.name"/> + </h2> + + <div class="row mt32 mb32" id="informations"> + <div t-if="doc.client_order_ref" class="col-auto mw-100 mb-2"> + <strong>Référence:</strong> + <p class="m-0" t-field="doc.client_order_ref"/> + </div> + <div t-if="doc.confirmation_date and doc.state not in ['draft','sent']" class="col-auto mw-100 mb-2"> + <strong>Date de la commande:</strong> + <p class="m-0" t-field="doc.confirmation_date"/> + </div> + <div t-if="doc.date_order and doc.state in ['draft','sent']" class="col-auto mw-100 mb-2"> + <strong>Date du devis:</strong> + <p class="m-0" t-field="doc.date_order"/> + </div> + <div t-if="doc.user_id.name" class="col-auto mw-100 mb-2"> + <strong>Vendeur:</strong> + <p class="m-0" t-field="doc.user_id"/> + </div> + <div t-if="doc.validity_date and doc.state in ['draft', 'sent']" class="col-auto mw-100 mb-2"> + <strong>Date d'Expiration:</strong> + <p class="m-0" t-field="doc.validity_date"/> + </div> + </div> + + <!-- Is there a discount on at least one line? --> + <t t-set="display_discount" t-value="any([l.discount for l in doc.order_line])"/> + + <table class="table table-sm o_main_table"> + <thead> + <tr> + <t t-set="colspan" t-value="5"/> + <th class="text-left">Description</th> + <th class="text-right">Quantité</th> + <th class="text-right">Prix unitaire</th> + <th t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line"> + <span>Réduc.(%)</span> + <t t-set="colspan" t-value="colspan+1"/> + </th> + <th class="text-right">Taxes</th> + <th class="text-right"> + <t groups="account.group_show_line_subtotals_tax_excluded">Montant</t> + <t groups="account.group_show_line_subtotals_tax_included">Sous-total</t> + </th> + </tr> + </thead> + <tbody class="sale_tbody"> + + <t t-set="current_subtotal" t-value="0"/> + + <t t-foreach="doc.order_line" t-as="line"> + + <t t-set="current_subtotal" t-value="current_subtotal + line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/> + <t t-set="current_subtotal" t-value="current_subtotal + line.price_total" groups="account.group_show_line_subtotals_tax_included"/> + + <tr t-att-class="'bg-200 font-weight-bold o_line_section' if line.display_type == 'line_section' else 'font-italic o_line_note' if line.display_type == 'line_note' else ''"> + <t t-if="not line.display_type"> + <td><span t-field="line.name"/></td> + <td class="text-right"> + <span t-field="line.product_uom_qty"/> + <span t-field="line.product_uom" groups="uom.group_uom"/> + </td> + <td class="text-right"> + <span t-field="line.price_unit"/> + </td> + <td t-if="display_discount" class="text-right" groups="sale.group_discount_per_so_line"> + <span t-field="line.discount"/> + </td> + <td class="text-right"> + <span t-esc="', '.join(map(lambda x: (x.description or x.name), line.tax_id))"/> + </td> + <td class="text-right o_price_total"> + <span t-field="line.price_subtotal" groups="account.group_show_line_subtotals_tax_excluded"/> + <span t-field="line.price_total" groups="account.group_show_line_subtotals_tax_included"/> + </td> + </t> + <t t-if="line.display_type == 'line_section'"> + <td t-att-colspan="colspan"> + <span t-field="line.name"/> + </td> + <t t-set="current_section" t-value="line"/> + <t t-set="current_subtotal" t-value="0"/> + </t> + <t t-if="line.display_type == 'line_note'"> + <td t-att-colspan="colspan"> + <span t-field="line.name"/> + </td> + </t> + </tr> + + <t t-if="current_section and (line_last or doc.order_line[line_index+1].display_type == 'line_section')"> + <tr class="is-subtotal text-right"> + <td t-att-colspan="colspan"> + <strong class="mr16">Sous-total</strong> + <span + t-esc="current_subtotal" + t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}' + /> + </td> + </tr> + </t> + </t> + </tbody> + </table> + + <div class="clearfix"> + <div id="total" class="row" name="total"> + <div t-attf-class="#{'col-4' if report_type != 'html' else 'col-sm-7 col-md-5'} ml-auto"> + <table class="table table-sm"> + <tr class="border-black o_subtotal" style=""> + <td><strong>Sous-total</strong></td> + <td class="text-right"> + <span t-field="doc.amount_untaxed"/> + </td> + </tr> + <t t-foreach="doc.amount_by_group" t-as="amount_by_group"> + <tr style=""> + <t t-if="amount_by_group[3] == 1 and doc.amount_untaxed == amount_by_group[2]"> + <td> + <span t-esc="amount_by_group[0]"/> + <span>&nbsp;<span>on</span>&nbsp;<t t-esc="amount_by_group[2]" t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/></span> + </td> + <td class="text-right o_price_total"> + <span t-esc="amount_by_group[1]" + t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/> + </td> + </t> + <t t-else =""> + <td> + <span t-esc="amount_by_group[0]"/> + </td> + <td class="text-right o_price_total"> + <span t-esc="amount_by_group[1]" + t-options='{"widget": "monetary", "display_currency": doc.pricelist_id.currency_id}'/> + </td> + </t> + </tr> + </t> + <tr class="border-black o_total"> + <td><strong>Total</strong></td> + <td class="text-right"> + <span t-field="doc.amount_total"/> + </td> + </tr> + </table> + </div> + </div> + </div> + + <p t-field="doc.note" /> + <p class="payment-term" t-if="doc.payment_term_id.note"> + <span t-field="doc.payment_term_id.note"/> + </p> + <p id="fiscal_position_remark" t-if="doc.fiscal_position_id and doc.fiscal_position_id.note"> + <strong>Position fiscale:</strong> + <span t-field="doc.fiscal_position_id.note"/> + </p> + + <div class="ml16 mr64 mb32" name="signature"> + <div class="offset-9 text-center"> + <strong>Signature</strong> + </div> + <div class="offset-9 bloc-signature "> + + </div> + </div> + + <div class="oe_structure"/> + </div> + </xpath> + </template> + + +</odoo> diff --git a/static/img/preview_background.png b/static/img/preview_background.png new file mode 100644 index 0000000000000000000000000000000000000000..cab3eae0dd04d1781810385b4ea17f41333d8b30 Binary files /dev/null and b/static/img/preview_background.png differ diff --git a/static/pdf/preview_background.pdf b/static/pdf/preview_background.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d33687c16b8914b5120268042d3bf8d84442c7de Binary files /dev/null and b/static/pdf/preview_background.pdf differ diff --git a/static/pdf/preview_boxed.pdf b/static/pdf/preview_boxed.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e73c1131d0416a424def4ea5742eb5d9a66e7c8e Binary files /dev/null and b/static/pdf/preview_boxed.pdf differ diff --git a/static/pdf/preview_clean.pdf b/static/pdf/preview_clean.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4f1c42b48142a978032b0f50f91bb5a00ecb8d17 Binary files /dev/null and b/static/pdf/preview_clean.pdf differ diff --git a/static/pdf/preview_standard.pdf b/static/pdf/preview_standard.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4d53737685051e86e2fa8156b96eec9cb2dd0b1d Binary files /dev/null and b/static/pdf/preview_standard.pdf differ diff --git a/static/src/scss/layout_boxed.scss b/static/src/scss/layout_boxed.scss new file mode 100644 index 0000000000000000000000000000000000000000..4870f512c8fe2964257c848dba24581f1ec61eaf --- /dev/null +++ b/static/src/scss/layout_boxed.scss @@ -0,0 +1,125 @@ +.o_boxed_footer, .o_boxed_header, .o_report_layout_boxed, a, .o_boxed_infos_societe { + font-family: 'Nunito', sans-serif; + color: #054357; + font-size: 13px; +} + +.bold-text{ + font-weight: 700; +} + +.o_boxed_footer, { + font-style: italic; + font-weight: 400; +} +.o_boxed_footer .title-footer{ + font-size: 14px; + font-style: italic; + font-weight: 700; +} +.o_boxed_header { + border-bottom: 0px solid #054357; + font-weight: 700; + img { + max-height: 100px; + } + h4 { + color: $o-we-color-text-normal; + font-weight: 700; + text-transform: uppercase; + } +} +.o_boxed_footer { + margin-top: 200px; + white-space: nowrap; + border-top: 3px solid #054357; + ul { + margin: 4px 0; + } +} +.o_report_layout_boxed { + > h2 { + text-transform: uppercase; + } + table { + border: 1px solid #054357; + thead { + border-bottom: 2px solid #054357; + tr th { + text-transform: uppercase; + border: 1px solid #054357; + } + } + tbody { + color: #054357; + tr { + td { + // remove border-top from standard layout + border-top: none; + border-right: 1px solid #054357; + } + &.o_line_section td, + &.o_line_note td, + &.is-subtotal td { + border-top: 1px solid #054357; + border-bottom: 1px solid #054357; + } + /*&.o_line_section td { + background-color: #054357; + color: #fff; + }*/ + /*&.is-subtotal, + td.o_price_total { + background-color: #054357; + }*/ + } + } + } + /* compat 12.0 */ + /*.page > table:not(.o_main_table) tr td:last-child { + background-color: #054357; + }*/ + /* compat 12.0 */ + /*.row:not(#total) > div > table tr:not(:first-child):not(:last-child) td:last-child { + background-color: #054357; + }*/ + /*Total table*/ + /* row div rule compat 12.0 */ + .row > div > table, + div#total table { + tr { + &:first-child, + &.o_subtotal { + border-bottom: 1px solid #054357; + + td:first-child { + border-right: none; + } + } + /*&:last-child td, + &.o_total td { + background-color: #054357; + color: #fff; + + &:first-child { + border-right: none; + } + }*/ + } + } +} + +.bloc-signature{ + height: 80px; + border-bottom: 1px solid #054357; +} + +.payment-term{ + font-size: 16px; + font-weight: 700; +} + +.address > div > address > address > div > span, +.address > div > div > address > div > span, .bene-name{ + font-size: 16px; +} diff --git a/views/account_invoice_view.xml b/views/account_invoice_view.xml index 5f7f58f18118c9f2921f9614e046cd96494e0da7..4d3ac0fe66633154b4fbdf212a5f4122adee43c4 100644 --- a/views/account_invoice_view.xml +++ b/views/account_invoice_view.xml @@ -8,7 +8,11 @@ <field name="inherit_id" ref="account.invoice_form"/> <field name="arch" type="xml"> <xpath expr="//field[@name='partner_id']" position="after"> - <field name="beneficiaire_id" /> + <field name="partner_is_beneficiaire" invisible="1"/> + <field name="beneficiaire_id" attrs="{'invisible': [('partner_is_beneficiaire','=',True)]}"/> + </xpath> + <xpath expr="//field[@name='reference']" position="attributes"> + <attribute name="readonly">{}</attribute> </xpath> </field> </record> diff --git a/views/report_templates.xml b/views/report_templates.xml new file mode 100644 index 0000000000000000000000000000000000000000..71848e1c2d8e1b349b8330c7560c52c2f131e5ce --- /dev/null +++ b/views/report_templates.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8"?> +<odoo> + <!-- Assets for reports --> + + <template id="autrement_report_assets_common" inherit_id="web.report_assets_common"> + <xpath expr="." position="inside"> + <link href="https://fonts.googleapis.com/css?family=Nunito:300,400,700" rel="stylesheet"/> + <link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet"/> + <link rel="stylesheet" type="text/scss" href="/autrement_dit_partner/static/src/scss/layout_boxed.scss"/> + </xpath> + </template> + + <template id="autrement_external_layout_boxed"> + <div class="header"> + <div class="o_boxed_header"> + <div class="row mb8"> + <div class="col-6"> + <img t-if="company.logo" t-att-src="image_data_uri(company.logo)" alt="Logo"/><br/><br/> + <t t-if="company.phone">Tel: <span t-field="company.phone"/></t> - + <t t-if="company.email"><a href="mailto:company.email"><span t-field="company.email"/></a></t> + </div> + + <div class="col-6 text-right mb4"> + + </div> + </div> + </div> + </div> + + <div class="article o_report_layout_boxed" t-att-data-oe-model="o and o._name" t-att-data-oe-id="o and o.id" t-att-data-oe-lang="o and o.env.context.get('lang')"> + <t t-call="web.address_layout"/> + <t t-raw="0"/> + <!-- <div class="o_boxed_infos_societe"> + <div class="row mb8"> + <div class="col-6"> + <span>TVA intracommunautaire n° : FR41524302502</span><br/> + <span>N° Formation professionnelle : 73 31 05751 31</span> + </div> + <div class="col-6"> + <span class="bold-text">Banque :</span> Société Générale - Code Banque : 30003<br/> + <span class="bold-text">Guichet :</span> 02149<br/> + <span class="bold-text">Num compte :</span> 00027000334 - Clé : 27<br/> + </div> + </div> + </div> --> + </div> + + <div class="footer o_boxed_footer"> + <div class="text-center"> + <div t-field="company.report_footer"/> + <div t-if="report_type == 'pdf'"> + Page: <span class="page"/> / <span class="topage"/> + </div> + </div> + </div> +<!-- + + <div class="footer o_boxed_footer"> + <div class="text-center"> + <p t-if="company.name" class="list-inline-item "><span class="title-footer" t-field="company.name"/>... + <t t-if="company.report_header" class="list-inline-item"><span class="title-footer" t-field="company.report_header"/></t><br/> + <span> + <span t-field="company.street"/> - + <span t-field="company.zip"/> + <span t-field="company.city"/> + </span><br/> + <span>SCOPARL à capital variable - N° SIRET : <span t-field="company.siret"/> - Code APE : <span t-field="company.ape"/> - Organisme de Formation n°73 31 057 51 31 - TVA intracommunautaire n° : <span t-field="company.vat"/></span> + </p> + <div t-field="company.report_footer"/> + <div t-if="report_type == 'pdf'"> + Page: <span class="page"/> / <span class="topage"/> + </div> + </div> + </div> --> + </template> + +</odoo> diff --git a/views/sale_view.xml b/views/sale_view.xml index 4141af1e230357b355767e39e64fb1489f13aa7e..ffdf9b74149e1743e2757df9ca174ed6dc67cd14 100644 --- a/views/sale_view.xml +++ b/views/sale_view.xml @@ -8,7 +8,8 @@ <field name="inherit_id" ref="sale.view_order_form"/> <field name="arch" type="xml"> <xpath expr="//field[@name='partner_id']" position="after"> - <field name="beneficiaire_id" /> + <field name="partner_is_beneficiaire" invisible="1"/> + <field name="beneficiaire_id" attrs="{'invisible': [('partner_is_beneficiaire','=',True)]}"/> </xpath> </field> </record>