Tower: upload laundry_management 19.0.19.0.4 (via marketplace)
This commit is contained in:
333
addons/laundry_management/report/laundry_order_report.xml
Normal file
333
addons/laundry_management/report/laundry_order_report.xml
Normal file
@@ -0,0 +1,333 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════════
|
||||
REPORT ACTION — Order Receipt
|
||||
model: sale.order (extended with is_laundry_order = True)
|
||||
═══════════════════════════════════════════════════════════════ -->
|
||||
<record id="action_report_laundry_order_receipt" model="ir.actions.report">
|
||||
<field name="name">Laundry Receipt / إيصال المغسلة</field>
|
||||
<field name="model">sale.order</field>
|
||||
<field name="report_type">qweb-pdf</field>
|
||||
<field name="report_name">laundry_management.report_laundry_order_receipt</field>
|
||||
<field name="report_file">laundry_management.report_laundry_order_receipt</field>
|
||||
<field name="print_report_name">'Receipt-%s' % (object.name)</field>
|
||||
<field name="binding_model_id" ref="sale.model_sale_order"/>
|
||||
<field name="binding_type">report</field>
|
||||
<field name="paperformat_id" ref="base.paperformat_euro"/>
|
||||
</record>
|
||||
|
||||
<!-- ═══════════════════════════════════════════════════════════════
|
||||
QWEB TEMPLATE — Bilingual Customer Receipt
|
||||
Field mapping (laundry.order → sale.order):
|
||||
customer_id → partner_id
|
||||
order_date → date_order / intake_date
|
||||
delivery_date → laundry_ready_date
|
||||
order_line_ids → order_line
|
||||
total_amount → amount_total
|
||||
amount_paid → amount_total - amount_due (computed inline)
|
||||
payment_status → laundry_payment_status
|
||||
priority → laundry_priority
|
||||
notes → laundry_notes
|
||||
line.quantity → line.product_uom_qty
|
||||
line.unit_price → line.price_unit
|
||||
line.subtotal → line.price_subtotal
|
||||
line.is_urgent → line.is_laundry_urgent
|
||||
═══════════════════════════════════════════════════════════════ -->
|
||||
<template id="report_laundry_order_receipt">
|
||||
<t t-call="web.html_container">
|
||||
<t t-foreach="docs" t-as="o">
|
||||
<t t-call="web.external_layout">
|
||||
<div class="page" style="font-family: Arial, sans-serif;">
|
||||
|
||||
<!-- ── Bilingual Header ── -->
|
||||
<div class="row mb-3 border-bottom pb-3">
|
||||
<div class="col-6">
|
||||
<h3 class="mb-0" style="color:#1a73e8;">
|
||||
Laundry Order Receipt
|
||||
</h3>
|
||||
<p class="text-muted mb-0" style="font-size:0.85em;">
|
||||
Customer Copy — Please retain for collection
|
||||
</p>
|
||||
</div>
|
||||
<div class="col-6 text-end" dir="rtl">
|
||||
<h3 class="mb-0" style="color:#1a73e8;">
|
||||
إيصال طلب المغسلة
|
||||
</h3>
|
||||
<p class="text-muted mb-0" style="font-size:0.85em;">
|
||||
نسخة العميل — يرجى الاحتفاظ به للاستلام
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Order Meta (bilingual columns) ── -->
|
||||
<div class="row mb-3">
|
||||
<div class="col-6">
|
||||
<table class="table table-sm table-borderless mb-0">
|
||||
<tr>
|
||||
<td style="width:45%;color:#666;">Order No.</td>
|
||||
<td><strong><t t-esc="o.name"/></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="color:#666;">Date</td>
|
||||
<td>
|
||||
<t t-esc="o.intake_date or o.date_order"
|
||||
t-options='{"widget":"date"}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<t t-if="o.laundry_ready_date">
|
||||
<tr>
|
||||
<td style="color:#666;">Expected Ready</td>
|
||||
<td>
|
||||
<strong>
|
||||
<t t-esc="o.laundry_ready_date"
|
||||
t-options='{"widget":"date"}'/>
|
||||
</strong>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<tr>
|
||||
<td style="color:#666;">Order Type</td>
|
||||
<td>
|
||||
<t t-esc="dict(o._fields['delivery_type'].selection).get(o.delivery_type, o.delivery_type)"/>
|
||||
</td>
|
||||
</tr>
|
||||
<t t-if="o.laundry_priority and o.laundry_priority != 'normal'">
|
||||
<tr>
|
||||
<td style="color:#666;">Priority</td>
|
||||
<td>
|
||||
<span style="color:#d93025;font-weight:bold;">
|
||||
<t t-esc="dict(o._fields['laundry_priority'].selection).get(o.laundry_priority)"/>
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-if="o.session_id">
|
||||
<tr>
|
||||
<td style="color:#666;">Session</td>
|
||||
<td><t t-esc="o.session_id.name"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-6" dir="rtl">
|
||||
<table class="table table-sm table-borderless mb-0">
|
||||
<tr>
|
||||
<td style="width:45%;color:#666;">رقم الطلب</td>
|
||||
<td><strong><t t-esc="o.name"/></strong></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td style="color:#666;">تاريخ الطلب</td>
|
||||
<td>
|
||||
<t t-esc="o.intake_date or o.date_order"
|
||||
t-options='{"widget":"date"}'/>
|
||||
</td>
|
||||
</tr>
|
||||
<t t-if="o.laundry_ready_date">
|
||||
<tr>
|
||||
<td style="color:#666;">موعد الجاهزية</td>
|
||||
<td>
|
||||
<strong>
|
||||
<t t-esc="o.laundry_ready_date"
|
||||
t-options='{"widget":"date"}'/>
|
||||
</strong>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<tr>
|
||||
<td style="color:#666;">نوع الطلب</td>
|
||||
<td>
|
||||
<t t-if="o.delivery_type == 'dropoff'">مراجعة مباشرة</t>
|
||||
<t t-if="o.delivery_type == 'pickup'">استلام من المنزل</t>
|
||||
<t t-if="o.delivery_type == 'delivery'">توصيل للمنزل</t>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Customer Block ── -->
|
||||
<div class="row mb-3"
|
||||
style="background:#f8f9fa;border-radius:6px;padding:10px;">
|
||||
<div class="col-6">
|
||||
<div style="color:#666;font-size:0.8em;text-transform:uppercase;">Customer</div>
|
||||
<strong style="font-size:1.1em;">
|
||||
<t t-esc="o.partner_id.name"/>
|
||||
</strong>
|
||||
<t t-if="o.mobile">
|
||||
<div><t t-esc="o.mobile"/></div>
|
||||
</t>
|
||||
<t t-elif="o.partner_id.phone">
|
||||
<div><t t-esc="o.partner_id.phone"/></div>
|
||||
</t>
|
||||
</div>
|
||||
<div class="col-6 text-end" dir="rtl">
|
||||
<div style="color:#666;font-size:0.8em;">العميل</div>
|
||||
<strong style="font-size:1.1em;">
|
||||
<t t-esc="o.partner_id.name"/>
|
||||
</strong>
|
||||
<t t-if="o.mobile">
|
||||
<div><t t-esc="o.mobile"/></div>
|
||||
</t>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Items Table ── -->
|
||||
<h6 style="color:#1a73e8;border-bottom:2px solid #1a73e8;padding-bottom:4px;">
|
||||
Services / الخدمات
|
||||
</h6>
|
||||
<table class="table table-sm table-bordered"
|
||||
style="font-size:0.9em;">
|
||||
<thead style="background:#1a73e8;color:white;">
|
||||
<tr>
|
||||
<th style="width:4%">#</th>
|
||||
<th>Service / الخدمة</th>
|
||||
<th>Color / اللون</th>
|
||||
<th>Notes / ملاحظات</th>
|
||||
<th class="text-end" style="width:6%">Qty</th>
|
||||
<th class="text-end" style="width:10%">Price</th>
|
||||
<th class="text-end" style="width:11%">Subtotal</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<t t-if="o.order_line">
|
||||
<t t-foreach="o.order_line" t-as="line">
|
||||
<tr t-attf-style="#{line.is_laundry_urgent and 'background:#fff3cd;' or ''}">
|
||||
<td><t t-esc="line_index + 1"/></td>
|
||||
<td>
|
||||
<t t-esc="line.product_id.name if line.product_id else ''"/>
|
||||
<t t-if="line.is_laundry_urgent">
|
||||
<span style="color:#d93025;font-size:0.75em;font-weight:bold;"> ⚡URGENT</span>
|
||||
</t>
|
||||
</td>
|
||||
<td><t t-esc="line.color or ''"/></td>
|
||||
<td>
|
||||
<t t-if="line.stain_note">
|
||||
<span style="color:#d93025;">
|
||||
<t t-esc="line.stain_note"/>
|
||||
</span>
|
||||
</t>
|
||||
<t t-elif="line.special_instructions">
|
||||
<t t-esc="line.special_instructions"/>
|
||||
</t>
|
||||
</td>
|
||||
<td class="text-end"><t t-esc="int(line.product_uom_qty)"/></td>
|
||||
<td class="text-end">
|
||||
<t t-esc="line.price_unit"
|
||||
t-options='{"widget":"monetary","display_currency":o.company_id.currency_id}'/>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<t t-esc="line.price_subtotal"
|
||||
t-options='{"widget":"monetary","display_currency":o.company_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</t>
|
||||
<t t-else="">
|
||||
<tr>
|
||||
<td colspan="7" class="text-center text-muted">
|
||||
No items on this order.
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr style="background:#f0f4ff;">
|
||||
<td colspan="6" class="text-end">
|
||||
<strong>Total / الإجمالي</strong>
|
||||
</td>
|
||||
<td class="text-end">
|
||||
<strong style="font-size:1.1em;">
|
||||
<t t-esc="o.amount_total"
|
||||
t-options='{"widget":"monetary","display_currency":o.company_id.currency_id}'/>
|
||||
</strong>
|
||||
</td>
|
||||
</tr>
|
||||
<t t-set="amount_paid" t-value="o.amount_total - o.amount_due"/>
|
||||
<t t-if="amount_paid > 0">
|
||||
<tr>
|
||||
<td colspan="6" class="text-end text-success">
|
||||
Paid / المدفوع
|
||||
</td>
|
||||
<td class="text-end text-success">
|
||||
<t t-esc="amount_paid"
|
||||
t-options='{"widget":"monetary","display_currency":o.company_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
<t t-if="o.amount_due > 0">
|
||||
<tr style="background:#f8d7da;">
|
||||
<td colspan="6" class="text-end text-danger fw-bold">
|
||||
Balance Due / المبلغ المتبقي
|
||||
</td>
|
||||
<td class="text-end text-danger fw-bold">
|
||||
<t t-esc="o.amount_due"
|
||||
t-options='{"widget":"monetary","display_currency":o.company_id.currency_id}'/>
|
||||
</td>
|
||||
</tr>
|
||||
</t>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<!-- ── Customer Notes ── -->
|
||||
<t t-if="o.laundry_notes">
|
||||
<div class="mt-3 p-2"
|
||||
style="border-left:3px solid #1a73e8;background:#f8f9fa;">
|
||||
<strong>Notes / ملاحظات:</strong>
|
||||
<span> <t t-esc="o.laundry_notes"/></span>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- ── Status + Payment ── -->
|
||||
<div class="row mt-3">
|
||||
<div class="col-6">
|
||||
<strong>Processing:</strong>
|
||||
<span t-attf-style="margin-left:6px;padding:2px 8px;border-radius:4px;
|
||||
background:#{o.laundry_state == 'delivered' and '#d4edda' or
|
||||
o.laundry_state in ('processing','ready') and '#fff3cd' or '#cfe2ff'};
|
||||
color:#{o.laundry_state == 'delivered' and '#155724' or
|
||||
o.laundry_state in ('processing','ready') and '#856404' or '#084298'};">
|
||||
<t t-esc="dict(o._fields['laundry_state'].selection).get(o.laundry_state, o.laundry_state)"/>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-6 text-end">
|
||||
<strong>Payment / الدفع:</strong>
|
||||
<span t-attf-style="margin-left:6px;padding:2px 8px;border-radius:4px;
|
||||
background:#{o.laundry_payment_status == 'paid' and '#d4edda' or
|
||||
o.laundry_payment_status == 'partial' and '#fff3cd' or '#f8d7da'};
|
||||
color:#{o.laundry_payment_status == 'paid' and '#155724' or
|
||||
o.laundry_payment_status == 'partial' and '#856404' or '#721c24'};">
|
||||
<t t-esc="dict(o._fields['laundry_payment_status'].selection).get(o.laundry_payment_status)"/>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- ── Staff Attribution ── -->
|
||||
<t t-if="o.received_by">
|
||||
<div class="text-muted mt-2" style="font-size:0.8em;">
|
||||
Received by: <t t-esc="o.received_by.name"/>
|
||||
<t t-if="o.delivered_by">
|
||||
 | 
|
||||
Handed over by: <t t-esc="o.delivered_by.name"/>
|
||||
</t>
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<!-- ── Footer ── -->
|
||||
<div class="text-center mt-4 pt-3 border-top"
|
||||
style="color:#666;font-size:0.8em;">
|
||||
<p class="mb-1">
|
||||
Thank you for choosing our laundry services.
|
||||
</p>
|
||||
<p class="mb-0" dir="rtl">
|
||||
شكراً لاختياركم خدمات مغسلتنا — نتطلع لخدمتكم دائماً
|
||||
</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</t>
|
||||
</t>
|
||||
</t>
|
||||
</template>
|
||||
|
||||
</odoo>
|
||||
Reference in New Issue
Block a user