617 lines
48 KiB
XML
617 lines
48 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<odoo>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- 1. Renewal Reminder - 3 days before expiry -->
|
|
<!-- ============================================================ -->
|
|
<record id="mail_template_rental_reminder" model="mail.template">
|
|
<field name="name">Rental: Renewal Reminder</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">{{ object.company_id.name }} - Rental {{ object.name }} Renews Soon</field>
|
|
<field name="email_from">{{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
|
|
<field name="partner_to">{{ object.partner_id.id }}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;max-width:600px;margin:0 auto;color:#2d3748;">
|
|
<div style="height:4px;background-color:#D69E2E;"></div>
|
|
<div style="background:#ffffff;padding:32px 28px;border:1px solid #e2e8f0;border-top:none;">
|
|
<p style="color:#D69E2E;font-size:13px;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;margin:0 0 24px 0;">
|
|
<t t-out="object.company_id.name"/>
|
|
</p>
|
|
<h2 style="color:#1a202c;font-size:22px;font-weight:700;margin:0 0 6px 0;line-height:1.3;">Rental Renewal Notice</h2>
|
|
<p style="color:#718096;font-size:15px;line-height:1.5;margin:0 0 24px 0;">
|
|
Your rental order <strong style="color:#2d3748;"><t t-out="object.name"/></strong> is scheduled for automatic renewal on <strong style="color:#2d3748;"><t t-out="object.rental_return_date and object.rental_return_date.strftime('%B %d, %Y') or ''"/></strong>.
|
|
</p>
|
|
<table style="width:100%;border-collapse:collapse;margin:0 0 24px 0;">
|
|
<tr><td colspan="2" style="padding:10px 14px;font-size:12px;font-weight:600;color:#718096;text-transform:uppercase;letter-spacing:0.5px;border-bottom:2px solid #e2e8f0;">Renewal Details</td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;border-bottom:1px solid #f0f0f0;width:35%;">Order</td><td style="padding:10px 14px;color:#2d3748;font-size:14px;border-bottom:1px solid #f0f0f0;"><t t-out="object.name"/></td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;border-bottom:1px solid #f0f0f0;">Renewal Date</td><td style="padding:10px 14px;color:#2d3748;font-size:14px;border-bottom:1px solid #f0f0f0;"><t t-out="object.rental_return_date and object.rental_return_date.strftime('%B %d, %Y') or ''"/></td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;font-weight:600;border-top:2px solid #e2e8f0;">Renewal Amount</td><td style="padding:10px 14px;color:#D69E2E;font-size:14px;font-weight:700;border-top:2px solid #e2e8f0;"><t t-out="object.amount_total" t-options="{'widget': 'monetary', 'display_currency': object.currency_id}"/></td></tr>
|
|
</table>
|
|
<div style="border-left:3px solid #D69E2E;padding:12px 16px;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;">If you would like to continue your rental, no action is needed. If you wish to cancel and schedule a pickup, click the button below.</p>
|
|
</div>
|
|
<div style="text-align:center;margin:0 0 24px 0;">
|
|
<a t-attf-href="{{ (object.get_base_url() or '') }}/rental/cancel/{{ ctx.get('cancel_token', '') }}" style="background-color:#E53E3E;color:#fff;padding:12px 30px;text-decoration:none;border-radius:4px;font-size:14px;font-weight:600;display:inline-block;">Request Cancellation & Pickup</a>
|
|
</div>
|
|
<t t-if="not is_html_empty(object.user_id.signature)" data-o-mail-quote-container="1">
|
|
<div data-o-mail-quote="1">--<br data-o-mail-quote="1"/><t t-out="object.user_id.signature or ''" data-o-mail-quote="1"/></div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</field>
|
|
<field name="lang">{{ object.partner_id.lang }}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- 2. Renewal Confirmation -->
|
|
<!-- ============================================================ -->
|
|
<record id="mail_template_rental_renewed" model="mail.template">
|
|
<field name="name">Rental: Renewal Confirmation</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">{{ object.company_id.name }} - Rental {{ object.name }} Renewed</field>
|
|
<field name="email_from">{{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
|
|
<field name="partner_to">{{ object.partner_id.id }}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;max-width:600px;margin:0 auto;color:#2d3748;">
|
|
<div style="height:4px;background-color:#38a169;"></div>
|
|
<div style="background:#ffffff;padding:32px 28px;border:1px solid #e2e8f0;border-top:none;">
|
|
<p style="color:#38a169;font-size:13px;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;margin:0 0 24px 0;">
|
|
<t t-out="object.company_id.name"/>
|
|
</p>
|
|
<h2 style="color:#1a202c;font-size:22px;font-weight:700;margin:0 0 6px 0;line-height:1.3;">Rental Renewed</h2>
|
|
<p style="color:#718096;font-size:15px;line-height:1.5;margin:0 0 24px 0;">
|
|
Your rental <strong style="color:#2d3748;"><t t-out="object.name"/></strong> has been successfully renewed.
|
|
</p>
|
|
<table style="width:100%;border-collapse:collapse;margin:0 0 24px 0;">
|
|
<tr><td colspan="2" style="padding:10px 14px;font-size:12px;font-weight:600;color:#718096;text-transform:uppercase;letter-spacing:0.5px;border-bottom:2px solid #e2e8f0;">New Rental Period</td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;border-bottom:1px solid #f0f0f0;width:35%;">New Start</td><td style="padding:10px 14px;color:#2d3748;font-size:14px;border-bottom:1px solid #f0f0f0;"><t t-out="object.rental_start_date and object.rental_start_date.strftime('%B %d, %Y') or ''"/></td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;border-bottom:1px solid #f0f0f0;">New Return</td><td style="padding:10px 14px;color:#2d3748;font-size:14px;border-bottom:1px solid #f0f0f0;"><t t-out="object.rental_return_date and object.rental_return_date.strftime('%B %d, %Y') or ''"/></td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;font-weight:600;border-top:2px solid #e2e8f0;">Renewal #</td><td style="padding:10px 14px;color:#38a169;font-size:14px;font-weight:700;border-top:2px solid #e2e8f0;"><t t-out="object.rental_renewal_count"/></td></tr>
|
|
</table>
|
|
<div style="border-left:3px solid #38a169;padding:12px 16px;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;" t-if="ctx.get('payment_ok')">Payment has been collected from your card on file. No further action is required.</p>
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;" t-if="not ctx.get('payment_ok')">Our team will be in touch regarding payment for this renewal period.</p>
|
|
</div>
|
|
<t t-if="not is_html_empty(object.user_id.signature)" data-o-mail-quote-container="1">
|
|
<div data-o-mail-quote="1">--<br data-o-mail-quote="1"/><t t-out="object.user_id.signature or ''" data-o-mail-quote="1"/></div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</field>
|
|
<field name="lang">{{ object.partner_id.lang }}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- 3. Payment Receipt -->
|
|
<!-- ============================================================ -->
|
|
<record id="mail_template_rental_payment_receipt" model="mail.template">
|
|
<field name="name">Rental: Payment Receipt</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">{{ object.company_id.name }} - Payment Receipt {{ object.name }}</field>
|
|
<field name="email_from">{{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
|
|
<field name="partner_to">{{ object.partner_id.id }}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;max-width:600px;margin:0 auto;color:#2d3748;">
|
|
<div style="height:4px;background-color:#2B6CB0;"></div>
|
|
<div style="background:#ffffff;padding:32px 28px;border:1px solid #e2e8f0;border-top:none;">
|
|
<p style="color:#2B6CB0;font-size:13px;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;margin:0 0 24px 0;">
|
|
<t t-out="object.company_id.name"/>
|
|
</p>
|
|
<h2 style="color:#1a202c;font-size:22px;font-weight:700;margin:0 0 6px 0;line-height:1.3;">Payment Receipt</h2>
|
|
<p style="color:#718096;font-size:15px;line-height:1.5;margin:0 0 24px 0;">
|
|
Payment has been collected for rental <strong style="color:#2d3748;"><t t-out="object.name"/></strong>.
|
|
</p>
|
|
<table style="width:100%;border-collapse:collapse;margin:0 0 24px 0;">
|
|
<tr><td colspan="2" style="padding:10px 14px;font-size:12px;font-weight:600;color:#718096;text-transform:uppercase;letter-spacing:0.5px;border-bottom:2px solid #e2e8f0;">Payment Details</td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;border-bottom:1px solid #f0f0f0;width:35%;">Reference</td><td style="padding:10px 14px;color:#2d3748;font-size:14px;border-bottom:1px solid #f0f0f0;"><t t-out="object.name"/></td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;border-bottom:1px solid #f0f0f0;">Rental Period</td><td style="padding:10px 14px;color:#2d3748;font-size:14px;border-bottom:1px solid #f0f0f0;"><t t-out="object.rental_start_date and object.rental_start_date.strftime('%B %d, %Y') or ''"/> to <t t-out="object.rental_return_date and object.rental_return_date.strftime('%B %d, %Y') or ''"/></td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;font-weight:600;border-top:2px solid #e2e8f0;">Amount Paid</td><td style="padding:10px 14px;color:#2B6CB0;font-size:14px;font-weight:700;border-top:2px solid #e2e8f0;"><t t-out="ctx.get('invoice') and ctx['invoice'].amount_total or object.amount_total" t-options="{'widget': 'monetary', 'display_currency': object.currency_id}"/></td></tr>
|
|
</table>
|
|
<div style="border-left:3px solid #2B6CB0;padding:12px 16px;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;">Thank you for your continued business. If you have any questions about this payment, please do not hesitate to contact us.</p>
|
|
</div>
|
|
<t t-if="not is_html_empty(object.user_id.signature)" data-o-mail-quote-container="1">
|
|
<div data-o-mail-quote="1">--<br data-o-mail-quote="1"/><t t-out="object.user_id.signature or ''" data-o-mail-quote="1"/></div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</field>
|
|
<field name="lang">{{ object.partner_id.lang }}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- 4. Cancellation Confirmation -->
|
|
<!-- ============================================================ -->
|
|
<record id="mail_template_rental_cancellation_confirmed" model="mail.template">
|
|
<field name="name">Rental: Cancellation Confirmed</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">{{ object.company_id.name }} - Cancellation Received {{ object.name }}</field>
|
|
<field name="email_from">{{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
|
|
<field name="partner_to">{{ object.partner_id.id }}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;max-width:600px;margin:0 auto;color:#2d3748;">
|
|
<div style="height:4px;background-color:#D69E2E;"></div>
|
|
<div style="background:#ffffff;padding:32px 28px;border:1px solid #e2e8f0;border-top:none;">
|
|
<p style="color:#D69E2E;font-size:13px;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;margin:0 0 24px 0;">
|
|
<t t-out="object.company_id.name"/>
|
|
</p>
|
|
<h2 style="color:#1a202c;font-size:22px;font-weight:700;margin:0 0 6px 0;line-height:1.3;">Cancellation Request Received</h2>
|
|
<p style="color:#718096;font-size:15px;line-height:1.5;margin:0 0 24px 0;">
|
|
Your cancellation request for rental <strong style="color:#2d3748;"><t t-out="object.name"/></strong> has been received. Your rental will <strong style="color:#2d3748;">no longer auto-renew</strong>.
|
|
</p>
|
|
<div style="border-left:3px solid #D69E2E;padding:12px 16px;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;">Our team will contact you shortly to schedule a pickup. If you have any questions in the meantime, please do not hesitate to reach out.</p>
|
|
</div>
|
|
<t t-if="not is_html_empty(object.user_id.signature)" data-o-mail-quote-container="1">
|
|
<div data-o-mail-quote="1">--<br data-o-mail-quote="1"/><t t-out="object.user_id.signature or ''" data-o-mail-quote="1"/></div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</field>
|
|
<field name="lang">{{ object.partner_id.lang }}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- 5. Send Agreement for Signing -->
|
|
<!-- ============================================================ -->
|
|
<record id="mail_template_rental_agreement" model="mail.template">
|
|
<field name="name">Rental: Agreement for Signing</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">{{ object.company_id.name }} - Rental Agreement {{ object.name }}</field>
|
|
<field name="email_from">{{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
|
|
<field name="partner_to">{{ object.partner_id.id }}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;max-width:600px;margin:0 auto;color:#2d3748;">
|
|
<div style="height:4px;background-color:#2B6CB0;"></div>
|
|
<div style="background:#ffffff;padding:32px 28px;border:1px solid #e2e8f0;border-top:none;">
|
|
<p style="color:#2B6CB0;font-size:13px;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;margin:0 0 24px 0;">
|
|
<t t-out="object.company_id.name"/>
|
|
</p>
|
|
<h2 style="color:#1a202c;font-size:22px;font-weight:700;margin:0 0 6px 0;line-height:1.3;">Rental Agreement</h2>
|
|
<p style="color:#718096;font-size:15px;line-height:1.5;margin:0 0 24px 0;">
|
|
Your rental order <strong style="color:#2d3748;"><t t-out="object.name"/></strong> is ready. Please review and sign the rental agreement and provide your payment details.
|
|
</p>
|
|
<table style="width:100%;border-collapse:collapse;margin:0 0 24px 0;">
|
|
<tr><td colspan="2" style="padding:10px 14px;font-size:12px;font-weight:600;color:#718096;text-transform:uppercase;letter-spacing:0.5px;border-bottom:2px solid #e2e8f0;">Agreement Details</td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;border-bottom:1px solid #f0f0f0;width:35%;">Order</td><td style="padding:10px 14px;color:#2d3748;font-size:14px;border-bottom:1px solid #f0f0f0;"><t t-out="object.name"/></td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;border-bottom:1px solid #f0f0f0;">Rental Period</td><td style="padding:10px 14px;color:#2d3748;font-size:14px;border-bottom:1px solid #f0f0f0;"><t t-out="object.rental_start_date and object.rental_start_date.strftime('%B %d, %Y') or ''"/> to <t t-out="object.rental_return_date and object.rental_return_date.strftime('%B %d, %Y') or ''"/></td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;font-weight:600;border-top:2px solid #e2e8f0;">Total</td><td style="padding:10px 14px;color:#2B6CB0;font-size:14px;font-weight:700;border-top:2px solid #e2e8f0;"><t t-out="object.amount_total" t-options="{'widget': 'monetary', 'display_currency': object.currency_id}"/></td></tr>
|
|
</table>
|
|
<div style="text-align:center;margin:0 0 24px 0;">
|
|
<a t-attf-href="{{ (object.get_base_url() or '') }}/rental/agreement/{{ object.id }}/{{ object.rental_agreement_token or '' }}" style="background-color:#2B6CB0;color:#fff;padding:12px 30px;text-decoration:none;border-radius:4px;font-size:14px;font-weight:600;display:inline-block;">Review & Sign Agreement</a>
|
|
</div>
|
|
<div style="border-left:3px solid #2B6CB0;padding:12px 16px;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;">Click the button above to review your rental agreement, provide your payment card details, and sign digitally. If you have any questions, please contact us.</p>
|
|
</div>
|
|
<t t-if="not is_html_empty(object.user_id.signature)" data-o-mail-quote-container="1">
|
|
<div data-o-mail-quote="1">--<br data-o-mail-quote="1"/><t t-out="object.user_id.signature or ''" data-o-mail-quote="1"/></div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</field>
|
|
<field name="lang">{{ object.partner_id.lang }}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- 6. Day-7 Marketing Email - Purchase Conversion -->
|
|
<!-- ============================================================ -->
|
|
<record id="mail_template_rental_marketing" model="mail.template">
|
|
<field name="name">Rental: Purchase Conversion Offer</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">{{ object.company_id.name }} - Make Your Rental Yours {{ object.name }}</field>
|
|
<field name="email_from">{{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
|
|
<field name="partner_to">{{ object.partner_id.id }}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;max-width:600px;margin:0 auto;color:#2d3748;">
|
|
<div style="height:4px;background-color:#319795;"></div>
|
|
<div style="background:#ffffff;padding:32px 28px;border:1px solid #e2e8f0;border-top:none;">
|
|
<p style="color:#319795;font-size:13px;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;margin:0 0 24px 0;">
|
|
<t t-out="object.company_id.name"/>
|
|
</p>
|
|
<h2 style="color:#1a202c;font-size:22px;font-weight:700;margin:0 0 6px 0;line-height:1.3;">Love Your Rental? Make It Yours!</h2>
|
|
<p style="color:#718096;font-size:15px;line-height:1.5;margin:0 0 24px 0;">
|
|
We hope you are enjoying your rental! Did you know you can purchase the product and apply your <strong style="color:#2d3748;">first month's rental as a discount</strong>?
|
|
</p>
|
|
<t t-if="object.rental_purchase_coupon_id">
|
|
<div style="padding:16px 20px;border:2px dashed #319795;border-radius:6px;text-align:center;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0 0 4px 0;font-size:12px;font-weight:600;color:#718096;text-transform:uppercase;letter-spacing:0.5px;">Your Exclusive Coupon</p>
|
|
<p style="margin:0;font-size:24px;font-weight:700;color:#319795;letter-spacing:2px;" t-out="object.rental_purchase_coupon_id.code or ''">CODE</p>
|
|
</div>
|
|
</t>
|
|
<p style="color:#718096;font-size:13px;line-height:1.5;margin:0 0 24px 0;">Delivery fee is not included in this offer.</p>
|
|
<div style="text-align:center;margin:0 0 24px 0;">
|
|
<a t-attf-href="{{ (object.get_base_url() or '') }}/rental/purchase-interest/{{ object.id }}/{{ object.rental_agreement_token or '' }}" style="background-color:#38a169;color:#fff;padding:12px 30px;text-decoration:none;border-radius:4px;font-size:14px;font-weight:600;display:inline-block;">I'm Interested!</a>
|
|
</div>
|
|
<div style="border-left:3px solid #319795;padding:12px 16px;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;">Click the button above to let us know, and a member of our team will follow up to discuss the details.</p>
|
|
</div>
|
|
<t t-if="not is_html_empty(object.user_id.signature)" data-o-mail-quote-container="1">
|
|
<div data-o-mail-quote="1">--<br data-o-mail-quote="1"/><t t-out="object.user_id.signature or ''" data-o-mail-quote="1"/></div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</field>
|
|
<field name="lang">{{ object.partner_id.lang }}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- 7. Security Deposit Refund Confirmation -->
|
|
<!-- ============================================================ -->
|
|
<record id="mail_template_rental_deposit_refund" model="mail.template">
|
|
<field name="name">Rental: Security Deposit Refunded</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">{{ object.company_id.name }} - Security Deposit Refunded {{ object.name }}</field>
|
|
<field name="email_from">{{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
|
|
<field name="partner_to">{{ object.partner_id.id }}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;max-width:600px;margin:0 auto;color:#2d3748;">
|
|
<div style="height:4px;background-color:#38a169;"></div>
|
|
<div style="background:#ffffff;padding:32px 28px;border:1px solid #e2e8f0;border-top:none;">
|
|
<p style="color:#38a169;font-size:13px;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;margin:0 0 24px 0;">
|
|
<t t-out="object.company_id.name"/>
|
|
</p>
|
|
<h2 style="color:#1a202c;font-size:22px;font-weight:700;margin:0 0 6px 0;line-height:1.3;">Security Deposit Refunded</h2>
|
|
<p style="color:#718096;font-size:15px;line-height:1.5;margin:0 0 24px 0;">
|
|
Your security deposit for rental order <strong style="color:#2d3748;"><t t-out="object.name"/></strong> has been refunded.
|
|
</p>
|
|
<t t-if="object.rental_deposit_invoice_id">
|
|
<table style="width:100%;border-collapse:collapse;margin:0 0 24px 0;">
|
|
<tr><td colspan="2" style="padding:10px 14px;font-size:12px;font-weight:600;color:#718096;text-transform:uppercase;letter-spacing:0.5px;border-bottom:2px solid #e2e8f0;">Refund Details</td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;border-bottom:1px solid #f0f0f0;width:35%;">Refund Amount</td><td style="padding:10px 14px;color:#2d3748;font-size:14px;border-bottom:1px solid #f0f0f0;"><t t-out="object.rental_deposit_invoice_id.amount_total" t-options="{'widget': 'monetary', 'display_currency': object.currency_id}"/></td></tr>
|
|
<tr><td style="padding:10px 14px;color:#718096;font-size:14px;font-weight:600;border-top:2px solid #e2e8f0;">Card</td><td style="padding:10px 14px;color:#38a169;font-size:14px;font-weight:700;border-top:2px solid #e2e8f0;">**** **** **** <t t-out="object._get_card_last_four() or '****'"/></td></tr>
|
|
</table>
|
|
</t>
|
|
<div style="border-left:3px solid #38a169;padding:12px 16px;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;">Please allow <strong>7 to 10 business days</strong> for the refund to appear on your statement, depending on your bank.</p>
|
|
</div>
|
|
<t t-if="not is_html_empty(object.user_id.signature)" data-o-mail-quote-container="1">
|
|
<div data-o-mail-quote="1">--<br data-o-mail-quote="1"/><t t-out="object.user_id.signature or ''" data-o-mail-quote="1"/></div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</field>
|
|
<field name="lang">{{ object.partner_id.lang }}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- 8. Thank You + Google Review -->
|
|
<!-- ============================================================ -->
|
|
<record id="mail_template_rental_thank_you" model="mail.template">
|
|
<field name="name">Rental: Thank You + Review</field>
|
|
<field name="model_id" ref="sale.model_sale_order"/>
|
|
<field name="subject">{{ object.company_id.name }} - Thank You {{ object.name }}</field>
|
|
<field name="email_from">{{ (object.user_id.email_formatted or object.company_id.email_formatted or user.email_formatted) }}</field>
|
|
<field name="partner_to">{{ object.partner_id.id }}</field>
|
|
<field name="body_html" type="html">
|
|
<div style="font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,Arial,sans-serif;max-width:600px;margin:0 auto;color:#2d3748;">
|
|
<div style="height:4px;background-color:#2B6CB0;"></div>
|
|
<div style="background:#ffffff;padding:32px 28px;border:1px solid #e2e8f0;border-top:none;">
|
|
<p style="color:#2B6CB0;font-size:13px;font-weight:600;letter-spacing:0.5px;text-transform:uppercase;margin:0 0 24px 0;">
|
|
<t t-out="object.company_id.name"/>
|
|
</p>
|
|
<h2 style="color:#1a202c;font-size:22px;font-weight:700;margin:0 0 6px 0;line-height:1.3;">Thank You!</h2>
|
|
<p style="color:#718096;font-size:15px;line-height:1.5;margin:0 0 24px 0;">
|
|
Thank you for choosing <strong style="color:#2d3748;"><t t-out="object.company_id.name or ''"/></strong> for your rental needs. Your rental order <strong style="color:#2d3748;"><t t-out="object.name"/></strong> has been completed and closed.
|
|
</p>
|
|
<t t-if="ctx.get('google_review_url')">
|
|
<div style="border-left:3px solid #2B6CB0;padding:12px 16px;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;">We would greatly appreciate your feedback. A review helps us serve you and others better!</p>
|
|
</div>
|
|
<div style="text-align:center;margin:0 0 24px 0;">
|
|
<a t-att-href="ctx.get('google_review_url', '#')" style="background-color:#2B6CB0;color:#fff;padding:12px 30px;text-decoration:none;border-radius:4px;font-size:14px;font-weight:600;display:inline-block;">Leave a Google Review</a>
|
|
</div>
|
|
</t>
|
|
<t t-else="">
|
|
<div style="border-left:3px solid #2B6CB0;padding:12px 16px;margin:0 0 24px 0;background:#f7fafc;">
|
|
<p style="margin:0;font-size:14px;line-height:1.5;color:#2d3748;">We hope you had a great experience. If you need anything in the future, do not hesitate to reach out.</p>
|
|
</div>
|
|
</t>
|
|
<t t-if="not is_html_empty(object.user_id.signature)" data-o-mail-quote-container="1">
|
|
<div data-o-mail-quote="1">--<br data-o-mail-quote="1"/><t t-out="object.user_id.signature or ''" data-o-mail-quote="1"/></div>
|
|
</t>
|
|
</div>
|
|
</div>
|
|
</field>
|
|
<field name="lang">{{ object.partner_id.lang }}</field>
|
|
<field name="auto_delete" eval="True"/>
|
|
</record>
|
|
|
|
<!-- ============================================================ -->
|
|
<!-- QWeb Pages -->
|
|
<!-- ============================================================ -->
|
|
|
|
<!-- Cancellation Form -->
|
|
<record id="cancellation_form_page" model="ir.ui.view">
|
|
<field name="name">Rental Cancellation Form</field>
|
|
<field name="type">qweb</field>
|
|
<field name="key">fusion_rental.cancellation_form_page</field>
|
|
<field name="arch" type="xml">
|
|
<t t-call="web.frontend_layout">
|
|
<div class="container py-5">
|
|
<div class="row justify-content-center">
|
|
<div class="col-md-8 col-lg-6">
|
|
<div class="card shadow-sm">
|
|
<div class="card-header bg-warning text-white"><h3 class="mb-0">Cancel Rental & Request Pickup</h3></div>
|
|
<div class="card-body">
|
|
<p>Cancellation for <strong t-out="order.name">SO001</strong>.</p>
|
|
<p><strong>Customer:</strong> <t t-out="partner.name">Name</t><br/><strong>Period Ends:</strong> <t t-out="order.rental_return_date and order.rental_return_date.strftime('%B %d, %Y') or ''">Date</t></p>
|
|
<form t-attf-action="/rental/cancel/{{ token }}" method="post">
|
|
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
|
|
<div class="mb-3"><label for="reason" class="form-label">Reason (optional)</label><textarea name="reason" id="reason" class="form-control" rows="3" placeholder="Let us know why..."/></div>
|
|
<button type="submit" class="btn btn-danger w-100">Confirm Cancellation & Request Pickup</button>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</t>
|
|
</field>
|
|
</record>
|
|
|
|
<!-- Cancellation Success -->
|
|
<record id="cancellation_success_page" model="ir.ui.view">
|
|
<field name="name">Rental Cancellation Success</field>
|
|
<field name="type">qweb</field>
|
|
<field name="key">fusion_rental.cancellation_success_page</field>
|
|
<field name="arch" type="xml">
|
|
<t t-call="web.frontend_layout">
|
|
<div class="container py-5"><div class="row justify-content-center"><div class="col-md-8 col-lg-6"><div class="card shadow-sm">
|
|
<div class="card-header bg-success text-white"><h3 class="mb-0">Cancellation Request Received</h3></div>
|
|
<div class="card-body text-center">
|
|
<i class="fa fa-check-circle text-success" style="font-size:48px;"/>
|
|
<p class="lead mt-3">Your cancellation for <strong t-out="order.name">SO001</strong> has been received.</p>
|
|
<p>Our team will contact you to schedule a pickup.</p>
|
|
</div>
|
|
</div></div></div></div>
|
|
</t>
|
|
</field>
|
|
</record>
|
|
|
|
<!-- Invalid Link -->
|
|
<record id="cancellation_invalid_page" model="ir.ui.view">
|
|
<field name="name">Rental Invalid Link</field>
|
|
<field name="type">qweb</field>
|
|
<field name="key">fusion_rental.cancellation_invalid_page</field>
|
|
<field name="arch" type="xml">
|
|
<t t-call="web.frontend_layout">
|
|
<div class="container py-5"><div class="row justify-content-center"><div class="col-md-8 col-lg-6"><div class="card shadow-sm">
|
|
<div class="card-header bg-danger text-white"><h3 class="mb-0">Invalid Request</h3></div>
|
|
<div class="card-body text-center">
|
|
<i class="fa fa-times-circle text-danger" style="font-size:48px;"/>
|
|
<p class="lead mt-3" t-out="error">This link is invalid or has already been used.</p>
|
|
<p>Please contact our office for assistance.</p>
|
|
</div>
|
|
</div></div></div></div>
|
|
</t>
|
|
</field>
|
|
</record>
|
|
|
|
<!-- Agreement Signing Page -->
|
|
<record id="agreement_signing_page" model="ir.ui.view">
|
|
<field name="name">Rental Agreement Signing</field>
|
|
<field name="type">qweb</field>
|
|
<field name="key">fusion_rental.agreement_signing_page</field>
|
|
<field name="arch" type="xml">
|
|
<t t-call="web.frontend_layout">
|
|
<div class="container py-4">
|
|
<div class="row justify-content-center">
|
|
<div class="col-lg-8">
|
|
<div class="card shadow-sm mb-4">
|
|
<div class="card-header bg-primary text-white"><h3 class="mb-0">Rental Agreement</h3></div>
|
|
<div class="card-body">
|
|
<h5>Order: <t t-out="order.name">SO001</t></h5>
|
|
<p><strong>Customer:</strong> <t t-out="partner.name">Name</t></p>
|
|
<p><strong>Rental Period:</strong>
|
|
<t t-out="order.rental_start_date and order.rental_start_date.strftime('%B %d, %Y') or ''">Start</t>
|
|
to <t t-out="order.rental_return_date and order.rental_return_date.strftime('%B %d, %Y') or ''">End</t>
|
|
</p>
|
|
|
|
<h5 class="mt-4">Order Summary</h5>
|
|
<table class="table table-sm table-bordered mb-0">
|
|
<thead class="table-light">
|
|
<tr><th>Description</th><th class="text-center" style="width:60px;">Qty</th><th class="text-end" style="width:120px;">Price</th></tr>
|
|
</thead>
|
|
<tbody>
|
|
<!-- Rental items -->
|
|
<t t-foreach="order.order_line.filtered(lambda l: l.is_rental and not l.is_security_deposit)" t-as="line">
|
|
<tr>
|
|
<td t-out="line.product_id.name">Product</td>
|
|
<td class="text-center" t-out="int(line.product_uom_qty)">1</td>
|
|
<td class="text-end"><t t-out="order.currency_id.symbol or '$'"/><t t-out="'%.2f' % line.price_subtotal"/></td>
|
|
</tr>
|
|
</t>
|
|
<!-- Non-rental, non-deposit items (delivery, installation, etc.) -->
|
|
<t t-foreach="order.order_line.filtered(lambda l: not l.is_rental and not l.is_security_deposit and not l.display_type)" t-as="line">
|
|
<tr>
|
|
<td t-out="line.product_id.name">Service</td>
|
|
<td class="text-center" t-out="int(line.product_uom_qty)">1</td>
|
|
<td class="text-end"><t t-out="order.currency_id.symbol or '$'"/><t t-out="'%.2f' % line.price_subtotal"/></td>
|
|
</tr>
|
|
</t>
|
|
<!-- Security deposit lines -->
|
|
<t t-foreach="order.order_line.filtered(lambda l: l.is_security_deposit)" t-as="line">
|
|
<tr class="table-warning">
|
|
<td><strong>SECURITY DEPOSIT - REFUNDABLE</strong>
|
|
<br/><small class="text-muted">REFUNDABLE UPON RETURN IN GOOD & CLEAN CONDITION</small></td>
|
|
<td class="text-center" t-out="int(line.product_uom_qty)">1</td>
|
|
<td class="text-end"><t t-out="order.currency_id.symbol or '$'"/><t t-out="'%.2f' % line.price_subtotal"/></td>
|
|
</tr>
|
|
</t>
|
|
</tbody>
|
|
<tfoot>
|
|
<tr class="table-light">
|
|
<td colspan="2" class="text-end"><strong>Total</strong></td>
|
|
<td class="text-end"><strong><t t-out="order.currency_id.symbol or '$'"/><t t-out="'%.2f' % order.amount_total"/></strong></td>
|
|
</tr>
|
|
</tfoot>
|
|
</table>
|
|
<div class="alert alert-info mt-2 small mb-4">
|
|
<strong>Payment will be processed in two portions:</strong>
|
|
<ol class="mb-0 mt-1">
|
|
<li>Rental charges, delivery and services</li>
|
|
<li>Refundable security deposit (separate invoice)</li>
|
|
</ol>
|
|
</div>
|
|
|
|
<h5 class="mt-4">Rental Agreement</h5>
|
|
<p class="text-muted small">Please review the full rental agreement below before signing.</p>
|
|
<div style="border:1px solid #dee2e6; border-radius:4px; overflow:hidden; margin-bottom:20px; background:#f8f9fa;">
|
|
<iframe t-att-src="pdf_preview_url"
|
|
style="width:100%; height:600px; border:none;"
|
|
title="Rental Agreement Preview"/>
|
|
</div>
|
|
<div class="form-check mb-3">
|
|
<input type="checkbox" class="form-check-input" id="agree_terms" required="1"/>
|
|
<label class="form-check-label" for="agree_terms">
|
|
I have read and agree to the terms and conditions of the Rental Agreement.
|
|
</label>
|
|
</div>
|
|
|
|
<hr/>
|
|
<h5>Credit Card Authorization</h5>
|
|
<p class="text-muted small">Your card will be securely tokenized. We do not store your full card number.</p>
|
|
<div class="row g-3">
|
|
<div class="col-12"><label class="form-label">Cardholder Name</label><input type="text" id="cardholder_name" class="form-control" placeholder="Name on card" required="1"/></div>
|
|
<div class="col-12"><label class="form-label">Card Number</label><input type="text" id="card_number" class="form-control" placeholder="1234 5678 9012 3456" maxlength="19" required="1"/></div>
|
|
<div class="col-4"><label class="form-label">Month</label><input type="text" id="exp_month" class="form-control" placeholder="MM" maxlength="2" required="1"/></div>
|
|
<div class="col-4"><label class="form-label">Year</label><input type="text" id="exp_year" class="form-control" placeholder="YYYY" maxlength="4" required="1"/></div>
|
|
<div class="col-4"><label class="form-label">CVV</label><input type="password" id="cvv" class="form-control" placeholder="***" maxlength="4" required="1"/></div>
|
|
</div>
|
|
|
|
<hr/>
|
|
<h5>Signature</h5>
|
|
<div class="mb-3"><label class="form-label">Full Name (Print)</label><input type="text" id="signer_name" class="form-control" t-att-value="partner.name" required="1"/></div>
|
|
<div class="mb-3">
|
|
<label class="form-label">Signature</label>
|
|
<div style="border:1px solid #ccc; border-radius:4px; background:#fff;">
|
|
<canvas id="signature_pad" width="600" height="200" style="width:100%; height:200px; cursor:crosshair;"/>
|
|
</div>
|
|
<button type="button" class="btn btn-sm btn-outline-secondary mt-1" id="clear_signature">Clear</button>
|
|
</div>
|
|
|
|
<div id="agreement_error" class="alert alert-danger d-none"></div>
|
|
<div id="agreement_success" class="alert alert-success d-none"></div>
|
|
|
|
<button type="button" id="btn_sign_agreement" class="btn btn-primary btn-lg w-100 mt-3"
|
|
t-att-data-order-id="order.id" t-att-data-token="token">
|
|
Sign Agreement & Authorize Card
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
var canvas = document.getElementById('signature_pad');
|
|
var ctx = canvas.getContext('2d');
|
|
var drawing = false;
|
|
|
|
function getPos(e) {
|
|
var rect = canvas.getBoundingClientRect();
|
|
var x = (e.touches ? e.touches[0].clientX : e.clientX) - rect.left;
|
|
var y = (e.touches ? e.touches[0].clientY : e.clientY) - rect.top;
|
|
return {x: x * (canvas.width / rect.width), y: y * (canvas.height / rect.height)};
|
|
}
|
|
|
|
canvas.addEventListener('mousedown', function(e) { drawing = true; ctx.beginPath(); var p = getPos(e); ctx.moveTo(p.x, p.y); });
|
|
canvas.addEventListener('mousemove', function(e) { if (!drawing) return; var p = getPos(e); ctx.lineTo(p.x, p.y); ctx.stroke(); });
|
|
canvas.addEventListener('mouseup', function() { drawing = false; });
|
|
canvas.addEventListener('touchstart', function(e) { e.preventDefault(); drawing = true; ctx.beginPath(); var p = getPos(e); ctx.moveTo(p.x, p.y); });
|
|
canvas.addEventListener('touchmove', function(e) { e.preventDefault(); if (!drawing) return; var p = getPos(e); ctx.lineTo(p.x, p.y); ctx.stroke(); });
|
|
canvas.addEventListener('touchend', function() { drawing = false; });
|
|
ctx.strokeStyle = '#000'; ctx.lineWidth = 2; ctx.lineCap = 'round';
|
|
|
|
document.getElementById('clear_signature').addEventListener('click', function() { ctx.clearRect(0, 0, canvas.width, canvas.height); });
|
|
|
|
document.getElementById('btn_sign_agreement').addEventListener('click', function() {
|
|
var btn = this;
|
|
var errDiv = document.getElementById('agreement_error');
|
|
var successDiv = document.getElementById('agreement_success');
|
|
errDiv.classList.add('d-none');
|
|
successDiv.classList.add('d-none');
|
|
|
|
var agreeCheck = document.getElementById('agree_terms');
|
|
if (agreeCheck && !agreeCheck.checked) {
|
|
errDiv.textContent = 'You must agree to the rental agreement terms before signing.';
|
|
errDiv.classList.remove('d-none');
|
|
return;
|
|
}
|
|
|
|
btn.disabled = true;
|
|
btn.textContent = 'Processing...';
|
|
|
|
var orderId = btn.dataset.orderId;
|
|
var token = btn.dataset.token;
|
|
var sigData = canvas.toDataURL('image/png');
|
|
|
|
fetch('/rental/agreement/' + orderId + '/' + token + '/sign', {
|
|
method: 'POST',
|
|
headers: {'Content-Type': 'application/json'},
|
|
body: JSON.stringify({
|
|
jsonrpc: '2.0', method: 'call', id: 1,
|
|
params: {
|
|
order_id: parseInt(orderId), token: token,
|
|
signer_name: document.getElementById('signer_name').value,
|
|
signature_data: sigData,
|
|
card_number: document.getElementById('card_number').value,
|
|
exp_month: document.getElementById('exp_month').value,
|
|
exp_year: document.getElementById('exp_year').value,
|
|
cvv: document.getElementById('cvv').value,
|
|
cardholder_name: document.getElementById('cardholder_name').value,
|
|
}
|
|
})
|
|
}).then(function(r) { return r.json(); }).then(function(data) {
|
|
var res = data.result || data;
|
|
if (res.success) {
|
|
successDiv.textContent = res.message || 'Signed successfully!';
|
|
successDiv.classList.remove('d-none');
|
|
btn.textContent = 'Signed!';
|
|
} else {
|
|
errDiv.textContent = res.error || 'An error occurred.';
|
|
errDiv.classList.remove('d-none');
|
|
btn.disabled = false;
|
|
btn.textContent = 'Sign Agreement & Authorize Card';
|
|
}
|
|
}).catch(function(e) {
|
|
errDiv.textContent = 'Network error. Please try again.';
|
|
errDiv.classList.remove('d-none');
|
|
btn.disabled = false;
|
|
btn.textContent = 'Sign Agreement & Authorize Card';
|
|
});
|
|
});
|
|
});
|
|
</script>
|
|
</t>
|
|
</field>
|
|
</record>
|
|
|
|
<!-- Purchase Interest Success -->
|
|
<record id="purchase_interest_success_page" model="ir.ui.view">
|
|
<field name="name">Rental Purchase Interest</field>
|
|
<field name="type">qweb</field>
|
|
<field name="key">fusion_rental.purchase_interest_success_page</field>
|
|
<field name="arch" type="xml">
|
|
<t t-call="web.frontend_layout">
|
|
<div class="container py-5"><div class="row justify-content-center"><div class="col-md-8 col-lg-6"><div class="card shadow-sm">
|
|
<div class="card-header bg-success text-white"><h3 class="mb-0">Thank You for Your Interest!</h3></div>
|
|
<div class="card-body text-center">
|
|
<i class="fa fa-shopping-cart text-success" style="font-size:48px;"/>
|
|
<p class="lead mt-3">We've received your interest in purchasing your rental product from order <strong t-out="order.name">SO001</strong>.</p>
|
|
<p>A member of our team will contact you shortly to discuss the details and schedule delivery.</p>
|
|
</div>
|
|
</div></div></div></div>
|
|
</t>
|
|
</field>
|
|
</record>
|
|
|
|
</odoo>
|