Files
project_v19/cpp_entry/views/portal_templates.xml
T
2026-07-01 14:41:49 +07:00

434 lines
31 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<!-- =======================================================
TEMPLATE: List of CPP Entries
======================================================= -->
<template id="portal_my_cpp_entries" name="My CPP Entries">
<t t-call="portal.portal_layout">
<div class="container mt-4 khmer-text">
<!-- Error Alert -->
<t t-if="error">
<div class="alert alert-danger alert-dismissible fade show">
<i class="fa fa-exclamation-triangle me-2"/>
<strong>Error:</strong> <t t-esc="error"/>
<button type="button" class="btn-close" data-bs-dismiss="alert"/>
</div>
</t>
<div class="d-flex justify-content-between align-items-center mb-4">
<h2><i class="fa fa-list-alt me-2"/>បញ្ជី</h2>
<a href="/my/cpp_entries/new" class="btn btn-primary">
<i class="fa fa-plus me-1"/>បង្កើតថ្មី
</a>
</div>
<t t-if="entries">
<div class="table-responsive">
<table class="table table-hover align-middle">
<thead class="table-light">
<tr>
<th>ថ្ងៃបង្កើត</th>
<th>រាជធានី/ខេត្ដ</th>
<th>ស្រុក/ខណ្ឌ</th>
<th>ឃុំ/សង្កាត់</th>
<th>ការិយាល័យបោះឆ្នោត</th>
<th class="text-center">អ្នកបោះឆ្នោត</th>
<th class="text-center">មិនទាន់បោះឆ្នោត</th>
<th class="text-end">សកម្មភាព</th>
</tr>
</thead>
<tbody>
<t t-foreach="entries" t-as="entry">
<tr>
<td><t t-esc="entry.create_date.strftime('%d/%m/%Y') if entry.create_date else '-'"/></td>
<td><t t-esc="entry.province_id.location_name or '-'"/></td>
<td><t t-esc="entry.district_id.location_name or '-'"/></td>
<td><t t-esc="entry.commune_id.location_name or '-'"/></td>
<td><t t-esc="entry.al_office or '-'"/></td>
<td class="text-center"><span class="badge bg-success"><t t-esc="entry.voter_count or 0"/></span></td>
<td class="text-center"><span class="badge bg-warning text-dark"><t t-esc="entry.non_voter_count or 0"/></span></td>
<td class="text-end">
<a t-attf-href="/my/cpp_entries/#{entry.id}" class="btn btn-sm btn-outline-primary">
<i class="fa fa-eye"/> មើល
</a>
</td>
</tr>
</t>
</tbody>
</table>
</div>
</t>
<t t-else="">
<div class="alert alert-info text-center">
<i class="fa fa-info-circle me-2"/>
មិនទាន់មានទិន្នន័យ។ <a href="/my/cpp_entries/new">ចុចទីនេះ</a> ដើម្បីបង្កើតថ្មី។
</div>
</t>
</div>
</t>
</template>
<!-- =======================================================
TEMPLATE: Main CPP Entry Form
======================================================= -->
<template id="portal_cpp_form" name="CPP Entry Form">
<t t-call="portal.portal_layout">
<div class="container mt-4 o_portal_cpp_form">
<!-- Error Alert -->
<t t-if="error">
<div class="alert alert-danger alert-dismissible fade show">
<i class="fa fa-exclamation-triangle me-2"/>
<strong>Error:</strong> <t t-esc="error"/>
<button type="button" class="btn-close" data-bs-dismiss="alert"/>
</div>
</t>
<h2 class="mb-4 text-primary">
<i class="fa fa-edit me-2"/>
<t t-if="entry.id">កែបញ្ជីឈ្មោះ</t>
<t t-else="">បង្កើតបញ្ជីឈ្មោះថ្មី</t>
</h2>
<form t-attf-action="/my/cpp_entries/submit" method="post" class="bg-white p-4 rounded shadow-sm border">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<input type="hidden" name="entry_id" t-att-value="entry.id or 0"/>
<!-- Location Section -->
<div class="row mb-4 p-3 bg-light rounded">
<div class="col-12 mb-2"><h5 class="fw-bold text-secondary">📍 ព័ត៌មានទីតាំង</h5></div>
<!-- Province -->
<div class="col-md-4 mb-3">
<label class="form-label fw-bold">រាជធានី/ខេត្ដ <span class="text-danger">*</span></label>
<select name="province_id" class="form-select" required="1" id="province_select">
<option value="">-- ជ្រើសរើសរាជធានី/ខេត្ដ --</option>
<t t-foreach="provinces" t-as="prov">
<option t-att-value="prov.id" t-att-selected="entry.province_id.id == prov.id">
<t t-esc="prov.location_name"/>
</option>
</t>
</select>
</div>
<!-- District -->
<div class="col-md-4 mb-3">
<label class="form-label fw-bold">ស្រុក/ខណ្ឌ</label>
<select name="district_id" class="form-select" id="district_select">
<option value="">-- ជ្រើសរើសស្រុក/ខណ្ឌ --</option>
<t t-if="entry.district_id">
<option t-att-value="entry.district_id.id" selected="selected">
<t t-esc="entry.district_id.location_name"/>
</option>
</t>
</select>
</div>
<!-- Commune -->
<div class="col-md-4 mb-3">
<label class="form-label fw-bold">ឃុំ/សង្កាត់</label>
<select name="commune_id" class="form-select" id="commune_select">
<option value="">-- ជ្រើសរើសឃុំ/សង្កាត់ --</option>
<t t-if="entry.commune_id">
<option t-att-value="entry.commune_id.id" selected="selected">
<t t-esc="entry.commune_id.location_name"/>
</option>
</t>
</select>
</div>
<div class="col-md-4 mb-3">
<label class="form-label fw-bold">លេខការិយាល័យ</label>
<input name="al_office" class="form-control form-control-lg" placeholder="លេខការិយាល័យ" t-att-value="entry.al_office or ''"/>
</div>
</div>
<!-- ✅ CONDITIONAL: Only show tables/buttons IF Entry is Saved -->
<t t-if="entry.id">
<!-- Table 1: Non-Voters List (Pink/Red) -->
<div class="card mb-4 border-danger">
<div class="card-header bg-danger text-white d-flex justify-content-between align-items-center">
<h5 class="mb-0">📋 បញ្ជីឈ្មោះអ្នកមិនទាន់បោះឆ្នោត</h5>
<span class="badge bg-light text-danger fs-6">
<t t-esc="len(entry.info_ids.filtered(lambda r: not r.status_vote))"/> នាក់
</span>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-bordered table-striped mb-0 align-middle">
<thead class="table-light">
<tr>
<th style="width:5%" class="text-center">ល.រ.</th>
<th style="width:8%">ភេទ</th>
<th style="width:20%">ឈ្មោះ</th>
<th style="width:12%">ថ្ងៃកំណើត</th>
<th style="width:25%">អាសយដ្ឋាន</th>
<!-- <th style="width:10%" class="text-center">ទូរសព្ទ</th>-->
<th style="width:10%" class="text-center">ជាសមាជិក</th>
<th style="width:12%" class="text-center">ស្ថានភាព</th>
<th style="width:12%" class="text-center">សកម្មភាព</th>
<th style="width:8%" class="text-center">រូប</th>
</tr>
</thead>
<tbody>
<t t-if="entry.info_ids.filtered(lambda r: not r.status_vote)">
<t t-foreach="entry.info_ids.filtered(lambda r: not r.status_vote)" t-as="voter">
<tr>
<td class="text-center fw-bold"><t t-esc="voter_index + 1"/></td>
<td>
<span t-if="voter.gender" t-attf-class="badge bg-#{'info' if voter.gender.name == 'ប្រុស' else 'danger'}">
<t t-esc="voter.gender.name or '-'"/>
</span>
<span t-else="" class="text-muted">-</span>
</td>
<td class="fw-medium"><t t-esc="voter.name or ''"/></td>
<td><t t-esc="voter.dob or '-'"/></td>
<td><t t-esc="voter.address or '-'"/></td>
<!-- <td class="text-center"><t t-esc="voter.phone or '-'"/></td>-->
<td><t t-esc="voter.cpp_member or '-'"/> </td>
<td class="text-center">
<span class="badge bg-warning text-dark">មិនទាន់បោះឆ្នោត</span>
</td>
<td class="text-center">
<!-- ✅ TOGGLE BUTTON: Mark as Voted -->
<a t-attf-href="/my/cpp_entries/voter/#{voter.id}/toggle_vote?csrf_token=#{request.csrf_token()}"
class="btn btn-sm btn-success py-0 me-1"
title="កំណត់ថាបានបោះឆ្នោត">
<i class="fa fa-check"/> បានបោះរួច
</a>
<a t-attf-href="/my/cpp_entries/voter/#{voter.id}/edit" class="btn btn-sm btn-outline-primary py-0 me-1"><i class="fa fa-pencil"/></a>
<!-- <a t-attf-href="/my/cpp_entries/voter/#{voter.id}/delete?csrf_token=#{request.csrf_token()}" class="btn btn-sm btn-outline-danger py-0" onclick="return confirm('តើអ្នកពិតជាចង់លុកឈ្មោះនេះមែនទេ?');"><i class="fa fa-trash"/></a>-->
</td>
<td class="text-center">
<t t-if="voter.photo">
<img t-att-src="image_data_uri(voter.photo)" class="rounded" style="width:40px;height:40px;object-fit:cover;" alt="Photo"/>
</t>
<t t-else=""><span class="text-muted small"></span></t>
</td>
</tr>
</t>
</t>
<t t-else="">
<tr><td colspan="9" class="text-center text-muted py-4"><i class="fa fa-info-circle me-1"/> មិនទាន់មានទិន្នន័យ</td></tr>
</t>
</tbody>
</table>
</div>
</div>
<div class="card-footer bg-white">
<a t-attf-href="/my/cpp_entries/voter/new?entry_id=#{entry.id}&amp;status_vote=0" class="btn btn-success btn-sm">
<i class="fa fa-plus me-1"/> បន្ថែមអ្នកមិនទាន់បោះឆ្នោត
</a>
</div>
</div>
<!-- Table 2: Voters List (Green) -->
<div class="card mb-4 border-success">
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
<h5 class="mb-0">✅ បញ្ជីឈ្មោះអនកបានបោះឆ្នោត</h5>
<span class="badge bg-light text-success fs-6">
<t t-esc="len(entry.info_ids.filtered(lambda r: r.status_vote))"/> នាក់
</span>
</div>
<div class="card-body p-0">
<div class="table-responsive">
<table class="table table-bordered table-striped mb-0 align-middle">
<thead class="table-light">
<tr>
<th style="width:5%" class="text-center">ល.រ.</th>
<th style="width:8%">ភេទ</th>
<th style="width:20%">ឈ្មោះ</th>
<th style="width:12%">ថ្ងៃកំណើត</th>
<th style="width:25%">អាសយដ្ឋាន</th>
<!-- <th style="width:10%" class="text-center">ទូរស័ព្ទ</th>-->
<th style="width:12%" class="text-center">ស្ថានភាព</th>
<th style="width:12%" class="text-center">សកម្មភាព</th>
<th style="width:8%" class="text-center">រូប</th>
</tr>
</thead>
<tbody>
<t t-if="entry.info_ids.filtered(lambda r: r.status_vote)">
<t t-foreach="entry.info_ids.filtered(lambda r: r.status_vote)" t-as="voter">
<tr>
<td class="text-center fw-bold"><t t-esc="voter_index + 1"/></td>
<td>
<span t-if="voter.gender" t-attf-class="badge bg-#{'info' if voter.gender.name == 'ប្រុស' else 'danger'}">
<t t-esc="voter.gender.name or '-'"/>
</span>
<span t-else="" class="text-muted">-</span>
</td>
<td class="fw-medium"><t t-esc="voter.name or ''"/></td>
<td><t t-esc="voter.dob or '-'"/></td>
<td><t t-esc="voter.address or '-'"/></td>
<!-- <td class="text-center"><t t-esc="voter.phone or '-'"/></td>-->
<td class="text-center">
<span class="badge bg-success">បោះឆ្នោតរួច</span>
</td>
<td class="text-center">
<!-- ✅ TOGGLE BUTTON: Mark as Not Voted -->
<a t-attf-href="/my/cpp_entries/voter/#{voter.id}/toggle_vote?csrf_token=#{request.csrf_token()}"
class="btn btn-sm btn-warning py-0 me-1"
title="កំណត់ថាមិនទាន់បោះឆ្នោត">
<i class="fa fa-undo"/> មិនទាន់បោះឆ្នោត
</a>
<a t-attf-href="/my/cpp_entries/voter/#{voter.id}/edit" class="btn btn-sm btn-outline-primary py-0 me-1"><i class="fa fa-pencil"/></a>
<a t-attf-href="/my/cpp_entries/voter/#{voter.id}/delete?csrf_token=#{request.csrf_token()}" class="btn btn-sm btn-outline-danger py-0" onclick="return confirm('តើអ្នកពិតជាចង់លុកឈ្មោះនេះមែនទេ?');"><i class="fa fa-trash"/></a>
</td>
<td class="text-center">
<t t-if="voter.photo">
<img t-att-src="image_data_uri(voter.photo)" class="rounded" style="width:40px;height:40px;object-fit:cover;" alt="Photo"/>
</t>
<t t-else=""><span class="text-muted small"></span></t>
</td>
</tr>
</t>
</t>
<t t-else="">
<tr><td colspan="9" class="text-center text-muted py-4"><i class="fa fa-info-circle me-1"/> មិនទាន់មានទិន្នន័យ</td></tr>
</t>
</tbody>
</table>
</div>
</div>
<!-- <div class="card-footer bg-white">-->
<!-- <a t-attf-href="/my/cpp_entries/voter/new?entry_id=#{entry.id}&amp;status_vote=1" class="btn btn-success btn-sm">-->
<!-- <i class="fa fa-plus me-1"/> បន្ថែមអ្នកបានបោះឆ្នោត-->
<!-- </a>-->
<!-- </div>-->
</div>
</t>
<t t-else="">
<!-- ✅ Info Message if entry is NOT saved yet -->
<div class="alert alert-info">
<i class="fa fa-info-circle me-2"/>
<strong>ចំណាំ:</strong> សូមចុច <b>"រក្សាទុក"</b> ដើម្បីបង្កើតបញ្ជីជាមុនសិន ទើបអាចបន្ថែមអ្នកបោះឆ្នោតបាន។
</div>
</t>
<!-- Action Buttons -->
<div class="d-flex justify-content-between mt-4 pt-3 border-top">
<a href="/my/cpp_entries" class="btn btn-outline-secondary px-4">
<i class="fa fa-arrow-left me-1"/> ត្រប់
</a>
<div>
<button type="submit" class="btn btn-primary px-5">
<i class="fa fa-save me-1"/> រក្សាទុកព័ត៌មាន
</button>
</div>
</div>
</form>
</div>
</t>
</template>
<!-- =======================================================
TEMPLATE: Voter Add/Edit Form
======================================================= -->
<template id="portal_voter_form" name="Voter Information Form">
<t t-call="portal.portal_layout">
<div class="container mt-4" style="max-width: 750px;">
<nav aria-label="breadcrumb" class="mb-4">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="/my">ផ្ទាំងគ្រប់គ្រង</a></li>
<li class="breadcrumb-item"><a href="/my/cpp_entries">CPP Entries</a></li>
<li class="breadcrumb-item"><a t-attf-href="/my/cpp_entries/#{entry.id}">បញ្ជី</a></li>
<li class="breadcrumb-item active">
<t t-if="voter.id">កែព័ត៌មាន</t>
<t t-else="">បន្ថែមថ្មី</t>
</li>
</ol>
</nav>
<div class="card shadow-sm border-0">
<div class="card-header bg-primary text-white">
<h4 class="mb-0"><i class="fa fa-user me-2"/>
<t t-if="voter.id">កែព័ត៌មានអ្នកបោះឆ្នោត</t>
<t t-else="">បន្ថែមអ្នកបោះឆ្នោតថ្មី</t>
</h4>
</div>
<form t-attf-action="/my/cpp_entries/voter/submit" method="post" enctype="multipart/form-data" class="card-body">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<!-- ✅ Hidden Fields for ID tracking -->
<input type="hidden" name="entry_id" t-att-value="entry.id"/>
<input type="hidden" name="voter_id" t-att-value="voter.id or 0"/>
<!-- Photo Upload Section -->
<div class="photo-upload-container text-center mb-4">
<div class="position-relative d-inline-block">
<!-- ✅ Show existing photo if available -->
<t t-if="voter.photo">
<img t-att-src="image_data_uri(voter.photo)"
id="photo_preview"
class="rounded-circle border border-3 border-light shadow"
style="width:120px;height:120px;object-fit:cover;display:block;"
alt="Profile Photo"/>
</t>
<!-- ✅ Show placeholder if no photo -->
<t t-else="">
<div class="photo-placeholder rounded-circle bg-light d-flex align-items-center justify-content-center border border-3 border-light shadow"
style="width:120px;height:120px;">
<i class="fa fa-user fa-3x text-muted"/>
</div>
</t>
<!-- ✅ Camera button with file input -->
<label for="photo_upload"
class="position-absolute bottom-0 end-0 btn btn-sm btn-primary rounded-circle shadow"
style="width:36px;height:36px;padding:0;line-height:36px;text-align:center;cursor:pointer;z-index:10;">
<i class="fa fa-camera" style="font-size:14px;"/>
<input type="file"
name="photo"
id="photo_upload"
class="d-none"
accept="image/*"/>
</label>
</div>
<small class="text-muted d-block mt-2">រូបថត (JPEG, PNG - អតិបរមា 2MB)</small>
</div>
<!-- Personal Info -->
<div class="row">
<div class="col-md-6 mb-3">
<label class="form-label fw-bold">ឈ្មោះ <span class="text-danger">*</span></label>
<input type="text" name="name" class="form-control form-control-lg" required="1" placeholder="បញ្ចូល្មោះពេញ" t-att-value="voter.name or ''"/>
</div>
<div class="col-md-6 mb-3">
<label class="form-label fw-bold">ភេទ</label>
<select name="gender" class="form-select form-select-lg">
<option value="">-- ជ្រើសរើសភេទ --</option>
<t t-foreach="genders" t-as="g">
<option t-att-value="g.id" t-att-selected="voter.gender.id == g.id"><t t-esc="g.name"/></option>
</t>
</select>
</div>
<div class="col-md-6 mb-3">
<label class="form-label fw-bold">ថ្ងៃខែឆ្នាំកំណើត</label>
<input type="date" name="dob" class="form-control form-control-lg" t-att-value="voter.dob"/>
</div>
<div class="col-md-6 mb-3">
<label class="form-label fw-bold">លេខទូរស័ព្ទ</label>
<input type="tel" name="phone" class="form-control form-control-lg" placeholder="012 345 678" t-att-value="voter.phone or ''"/>
</div>
<div class="col-12 mb-3">
<label class="form-label fw-bold">អាសយដ្ឋាន</label>
<textarea name="address" class="form-control" rows="3" placeholder="បញ្ចូលអាសយដ្ឋានពេញ" t-esc="voter.address or ''"/>
</div>
<div class="col-12 mb-4">
<div class="form-check form-switch">
<input class="form-check-input" type="checkbox" name="status_vote" id="status_vote" t-att-checked="'checked' if status_vote == 1 else None"/>
<label class="form-check-label fw-bold" for="status_vote">✅ បោះឆ្នោតរួច</label>
</div>
</div>
</div>
<div class="d-flex justify-content-between mt-4 pt-3 border-top">
<a t-attf-href="/my/cpp_entries/#{entry.id}" class="btn btn-outline-secondary px-4"><i class="fa fa-times me-1"/> បោះបង់</a>
<button type="submit" class="btn btn-primary px-5">
<i class="fa fa-save me-1"/> <t t-if="voter.id">កែប្រែ</t><t t-else="">បន្ថែម</t>
</button>
</div>
</form>
</div>
</div>
</t>
</template>
</odoo>