[IMP] sale_coupon: Allow to print and send coupons by email

Purpose
=======

A feature was not done when doing the coupon task because of the lack of time : Coupon should be printed from the system and same can be sent to customer via email(attractive email template).

Specification
=============

Ass the possibility to:

- Print coupon
- Send coupon by email with the printed report in attachment
- Generated coupon by sending to the customers the coupon in attachments
This commit is contained in:
Sagar Ahirrao
2017-12-01 13:04:30 +01:00
committed by Yannick Tivisse
parent 8e3b2184f2
commit 96fed80454
12 changed files with 322 additions and 28 deletions
+1
View File
@@ -3,3 +3,4 @@
from . import models
from . import wizard
from . import report
+3 -1
View File
@@ -15,6 +15,8 @@
'views/sale_coupon_views.xml',
'views/sale_coupon_program_views.xml',
'views/res_config_settings_views.xml',
'data/sale_coupon_data.xml',
'report/sale_coupon_report.xml',
'report/sale_coupon_report_templates.xml',
'data/sale_coupon_email_data.xml',
],
}
-11
View File
@@ -1,11 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="sale_coupon_created_coupon_email_template">
<div>
<h2>Congratulations!</h2>
Enter the following coupon code (<i><t t-esc="code"/></i>) during your next purchase to receive this discount: <b><t t-esc="reward_description"/></b>.
</div>
</template>
</odoo>
+173
View File
@@ -0,0 +1,173 @@
<?xml version="1.0" ?>
<odoo>
<data>
<record id="sale_coupon.mail_template_sale_coupon" model="mail.template">
<field name="name">Coupon - Send by Email</field>
<field name="email_from">${object.program_id.company_id.email|safe}</field>
<field name="subject">Your reward coupon from ${object.program_id.company_id.name} </field>
<field name="partner_to">${object.partner_id.id}</field>
<field name="model_id" ref="sale_coupon.model_sale_coupon"/>
<field name="auto_delete" eval="True"/>
<field name="report_template" ref="report_coupon_code"/>
<field name="report_name">Your Coupon Code</field>
<field name="lang">${object.partner_id.lang}</field>
<field name="body_html" type="xml">
<div style="margin:auto;background-color:rgb(255, 255, 255);border: 1px solid rgb(240, 240, 240);max-width:600px;width:100%;">
<table align="center" style="text-align: center;" cellspacing="0" cellpadding="0" border="0" width="100%">
<tbody>
<tr>
<td width="70%" style="padding:20px 20px 20px 20px;vertical-align:middle;text-align: left;border-bottom: 3px solid rgb(255, 255, 255)">
<img src="/logo?company=${object.program_id.company_id.id}" alt="${object.program_id.company_id.name}" style="border:0px solid transparent; height: auto; max-width: 150px;" height="29"/>
</td>
</tr>
% if object.partner_id.name:
<tr>
<td style="padding: 5px 0px 0px 0px;">
<span>
<b> Congratulations </b> ${object.partner_id.name},
</span>
</td>
</tr>
% endif
<tr>
<td>
<div>Here is your reward from ${object.program_id.company_id.name}.</div>
<p class="oe_mt16"></p>
</td>
</tr>
% if object.program_id.reward_type == 'discount':
% if object.program_id.discount_type == 'fixed_amount':
<tr>
<td>
<div style="font-size: 50px; color: rgb(153, 51, 102);font-weight: bold;">
${'%s' % (format_amount(object.program_id.discount_fixed_amount, object.program_id.currency_id))}
</div>
</td>
</tr>
<tr>
<td>
<div style="font-size: 24px;">
OFF ON YOUR NEXT ORDER !
</div>
</td>
</tr>
%else
<tr>
<td>
<div style="font-size: 50px; color: rgb(153, 51, 102);font-weight: bold;">
${object.program_id.discount_percentage} %
</div>
</td>
</tr>
% if object.program_id.discount_apply_on == 'specific_product':
<tr>
<td>
<div style="font-size: 24px;">
${'ON %s' % (object.program_id.discount_specific_product_id.name.upper())}
</div>
</td>
</tr>
% elif object.program_id.discount_apply_on == 'cheapest_product':
<tr>
<td>
<div style="font-size: 24px;">
OFF ON THE CHEAPEST PRODUCT !
</div>
</td>
</tr>
% else
<tr>
<td>
<div style="font-size: 24px;">
OFF ON YOUR NEXT ORDER !
</div>
</td>
</tr>
% endif
% endif
% elif object.program_id.reward_type == 'product':
<tr>
<td>
<div style="font-size: 24px;">
${'GET %s FREE %s ON YOUR NEXT ORDER !' % (object.program_id.reward_product_quantity, object.program_id.reward_product_id.name.upper())}
</div>
</td>
</tr>
% elif object.program_id.reward_type == 'free_shipping':
<tr>
<td>
<div style="font-size: 24px;">
${'GET FREE SHIPPING ON YOUR NEXT ORDER !'}
</div>
</td>
</tr>
% endif
<tr>
<td>
<span>
<font style="font-size: 18px;">
Use this promo code
</font>
% if object.expiration_date:
<font style="font-size: 18px;">
before ${object.expiration_date}
</font>
% endif
</span>
</td>
</tr>
<tr>
<td>
<span>
<font style="font-size: 20px;">CODE:</font>
<strong style="padding: 5px;border-radius: 3px;background-color:#D9EAD3;font-size:18px;color:rgb(70, 70, 70);font-family:monospace;font-weight: bold;">
${object.code}
</strong>
</span>
</td>
</tr>
<tr>
<td>
% if object.program_id.rule_min_quantity not in [0, 1]
<span>
<font style="font-size: 14px;">
Minimum purchase of ${object.program_id.rule_min_quantity} products
</font>
</span>
% endif
</td>
</tr>
<tr>
<td>
% if object.program_id.rule_minimum_amount != 0.00
<span>
<font style="font-size: 14px;">
Valid for purchase above ${object.program_id.company_id.currency_id.symbol}${'%0.2f' % object.program_id.rule_minimum_amount |float}
</font>
</span>
% endif
</td>
</tr>
<tr>
<td style="padding: 20px 0px 20px 0px; border-top: 3px solid rgb(255, 255, 255);">
% if object.program_id.company_id.name:
<span style="font-family:&quot;Lucida Grande&quot;, Helvetica, Verdana, Arial, sans-serif;color: rgb(147, 147, 147);">
<strong>
${object.program_id.company_id.name}
</strong>
</span>
<div>
<p style="font-family:&quot;Lucida Grande&quot;, Helvetica, Verdana, Arial, sans-serif;text-align: center;color: rgb(147, 147, 147);font-weight: bold;font-size: 9px;">
Copyright © All Rights Reserved
</p>
</div>
% endif
</td>
</tr>
</tbody>
</table>
</div>
</field>
</record>
</data>
</odoo>
+27
View File
@@ -81,3 +81,30 @@ class SaleCoupon(models.Model):
if self.program_id not in applicable_programs and self.program_id.promo_applicability == 'on_current_order':
message = {'error': _('At least one of the required conditions is not met to get the reward!')}
return message
@api.multi
def action_coupon_sent(self):
""" Open a window to compose an email, with the edi invoice template
message loaded by default
"""
self.ensure_one()
template = self.env.ref('sale_coupon.mail_template_sale_coupon', False)
compose_form = self.env.ref('mail.email_compose_message_wizard_form', False)
ctx = dict(
default_model='sale.coupon',
default_res_id=self.id,
default_use_template=bool(template),
default_template_id=template.id,
default_composition_mode='comment',
)
return {
'name': _('Compose Email'),
'type': 'ir.actions.act_window',
'view_type': 'form',
'view_mode': 'form',
'res_model': 'mail.compose.message',
'views': [(compose_form.id, 'form')],
'view_id': compose_form.id,
'target': 'new',
'context': ctx,
}
+3 -6
View File
@@ -155,12 +155,9 @@ class SaleOrder(models.Model):
'discount_line_product_id': program.discount_line_product_id.id
})
self.generated_coupon_ids |= coupon
subject = '%s, a coupon has been generated from your order %s' % (self.partner_id.name, self.name)
body = self.env.ref('sale_coupon.sale_coupon_created_coupon_email_template').render({
'code': coupon.code,
'reward_description': coupon.program_id.discount_line_product_id.name
})
self.message_post(body=body, subject=subject, subtype='mail.mt_comment', partner_ids=[(4, self.partner_id.id)])
template = self.env.ref('sale_coupon.mail_template_sale_coupon', raise_if_not_found=False)
if template:
self.message_post_with_template(template.id, composition_mode='comment')
return coupon
def _get_applicable_programs(self):
+4
View File
@@ -0,0 +1,4 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import sale_coupon_report
+18
View File
@@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import api, models
class CouponReport(models.AbstractModel):
_name = 'report.sale_coupon.report_coupon'
@api.model
def get_report_values(self, docids, data=None):
docs = self.env['sale.coupon'].browse(docids)
return {
'doc_ids': docs.ids,
'doc_model': 'sale.coupon',
'data': data,
'docs': docs,
}
+12
View File
@@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data>
<report
id="report_coupon_code"
model="sale.coupon"
name="sale_coupon.report_coupon"
file="sale_coupon.report_coupon"
report_type="qweb-pdf"
string="Coupon Code"/>
</data>
</odoo>
+77
View File
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="report_coupon">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="o">
<t t-call="web.internal_layout">
<div class="panel panel-default">
<div class="panel-body">
<div class="page">
<div class="row text-center">
<div class="o_offer col-md-12">
<h4 t-if="o.partner_id.name">
Congratulations
<t t-esc="o.partner_id.name"/>,
</h4>
<t t-set="text" t-value="'OFF ON YOUR NEXT ORDER !'"/>
<t t-if="o.program_id.reward_type == 'discount'">
<h1 t-if="o.program_id.discount_type == 'fixed_amount'" class="text-success">
<strong><span t-field="o.program_id.discount_fixed_amount" t-options='{"widget": "monetary", "display_currency": o.program_id.currency_id}'/></strong>
</h1>
<h1 t-if="o.program_id.discount_type == 'percentage'" class="text-success">
<strong><span t-field="o.program_id.discount_percentage"/>%</strong>
</h1>
<t t-if="o.program_id.discount_apply_on == 'specific_product'">
<t t-set="text" t-value="'OFF ON %s' % (o.program_id.discount_specific_product_id.name.upper())"/>
</t>
<t t-if="o.program_id.discount_apply_on == 'cheapest_product'">
<t t-set="text" t-value="'%s' % ('OFF ON THE CHEAPEST PRODUCT')"/>
</t>
</t>
<t t-if="o.program_id.reward_type == 'product'">
<t t-set="text" t-value="'GET %s FREE %s ON YOUR NEXT ORDER !' % (o.program_id.reward_product_quantity, o.program_id.reward_product_id.name.upper())"/>
</t>
<t t-if="o.program_id.reward_type == 'free_shipping'">
<t t-set="text" t-value="'GET FREE SHIPPING ON YOUR NEXT ORDER !'"/>
</t>
<h3 t-esc="text"/>
<h3 t-if="o.expiration_date">
Use this promo code before
<strong t-field="o.expiration_date" t-options='{"format": "d MMMM y"}'/>
</h3>
<h3>
<em>CODE :</em>
<strong class="bg-success" t-esc="o.code"></strong>
</h3>
<h4 t-if="o.program_id.rule_min_quantity > 1">
Minimum purchase of
<strong t-esc="o.program_id.rule_min_quantity"/> products
</h4>
<h4 t-if="o.program_id.rule_minimum_amount">
Valid for purchase above
<strong t-esc="o.program_id.rule_minimum_amount" t-options="{'widget': 'monetary', 'display_currency': o.program_id.currency_id}"/>
</h4>
<br/>
<img t-att-src="'/report/barcode/Code128/%s' % o.code"/>
<br/>
<div class="mt64">
<div class="col-xs-6 text-right">
<img t-att-src="'/logo?company=%d' % (o.program_id.company_id)" t-att-alt="'%s' % (o.program_id.company_id.name)" style="border:0px solid transparent; height: 50; width: 200px;" height="50"/>
</div>
<div class="col-xs-6 text-left">
<span t-field="o.program_id.company_id.partner_id"
t-options='{"widget": "contact", "fields": ["address", "email"], "no_marker": True}'/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</t>
</t>
</t>
</template>
</odoo>
+1
View File
@@ -30,6 +30,7 @@
<field name="arch" type="xml">
<form string="Coupons" create="false" edit="false" delete="false">
<header>
<button name="action_coupon_sent" type="object" string="Send by Email" class="oe_highlight"/>
<field name="state" widget="statusbar" statusbar_visible="new,used,expired" context="{'state': state}"/>
</header>
<sheet>
+3 -10
View File
@@ -31,13 +31,6 @@ class SaleCouponGenerate(models.TransientModel):
vals.update({'partner_id': partner.id})
coupon = self.env['sale.coupon'].create(vals)
subject = '%s, a coupon has been generated for you' % (partner.name)
body = self.env.ref('sale_coupon.sale_coupon_created_coupon_email_template').render({
'code': coupon.code,
'reward_description': coupon.program_id.discount_line_product_id.name
})
self.env['mail.mail'].create({
'subject': subject,
'body': body,
'email_from': self.env.user.email or '',
'email_to': partner.email,
})
template = self.env.ref('sale_coupon.mail_template_sale_coupon', raise_if_not_found=False)
if template:
template.send_mail(coupon.id, email_values={'email_to': partner.email, 'email_from': self.env.user.email or '', 'subject': subject,})