Merge pull request #5188 from expsa/takaful_catelog_updates

[IMP] donation_details_lines: add donation amount field; update donat…
This commit is contained in:
Tahir Hassan 2025-11-03 18:13:51 +04:00 committed by GitHub
commit 5c29f36027
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 107 additions and 120 deletions

View File

@ -388,6 +388,7 @@ class DonationsDetailsLines(models.Model):
"donation_types": 'donation',
"name": product.name,
"donation_qty": _qty,
"donation_amount": product.lst_price
})
else:
if existing:

View File

@ -328,6 +328,7 @@ class TakafulSponsorship(models.Model):
"donation_types": 'donation',
"name": product.name,
"donation_qty": _qty,
"donation_amount": product.lst_price
})
else:
# remove if qty <= 0

View File

@ -3,6 +3,13 @@
// Attach event handlers immediately using event delegation
// Odoo converts 'name' attribute to 'data-name' in rendered HTML
$(document).on('click', 'button[data-name="add_quantity_button_request"]', function(e) {
e.preventDefault();
e.stopPropagation();
handleQuantityChange($(this), 'first_add');
return false; // ensure Odoo's default kanban action handler does not run
});
$(document).on('click', 'button[data-name="add_quantity_button_so"]', function(e) {
e.preventDefault();
e.stopPropagation();
@ -24,6 +31,9 @@ window.__dc_add = function(btn) {
window.__dc_remove = function(btn) {
return __dc_handle(btn, 'remove');
};
window.__dc_first_add = function(btn) {
return __dc_handle(btn, 'first_add');
};
function __dc_handle(btn, operation) {
try {
@ -36,6 +46,7 @@ function __dc_handle(btn, operation) {
}
async function handleQuantityChange($button, operation) {
// Get the kanban record (product card) container
const $kanbanRecord = $button.closest('.o_kanban_record');
if (!$kanbanRecord.length) {
@ -43,24 +54,26 @@ async function handleQuantityChange($button, operation) {
}
// Get quantity display element from the button's parent container using stable custom classes
const $container = $button.closest('.dc-qty-controls');
const $quantityDisplay = $container.find('.dc-qty-badge');
if (!$quantityDisplay.length) {
return;
let $container = $button.closest('.dc-qty-controls');
if (operation === 'first_add'){
$container = $kanbanRecord.find('.dc-qty-controls')
}
let $quantityDisplay = $container.find('.dc-qty-badge');
// if (!$quantityDisplay.length) {
// return;
// }
// Extract product ID from the image URL
const $img = $kanbanRecord.find('.o_kanban_image img');
if (!$img.length) {
return;
}
// if (!$img.length) {
// return;
// }
const imgSrc = $img.attr('src');
const match = imgSrc.match(/[&?]id=(\d+)/);
if (!match || !match[1]) {
return;
}
// if (!match || !match[1]) {
// return;
// }
const productId = parseInt(match[1]);
let currentQuantity = parseFloat($quantityDisplay.text()) || 0;
@ -68,10 +81,6 @@ async function handleQuantityChange($button, operation) {
// Prevent going below zero for remove operation
if (operation === 'remove' && currentQuantity <= 0) {
$quantityDisplay.addClass('bg-warning').removeClass('bg-secondary');
setTimeout(() => {
$quantityDisplay.removeClass('bg-warning').addClass('bg-secondary');
}, 300);
return;
}
@ -108,16 +117,22 @@ async function handleQuantityChange($button, operation) {
// Calculate new quantity
let newQuantity = currentQuantity;
if (operation === 'add') {
newQuantity += 1;
} else if (operation === 'remove') {
newQuantity -= 1;
if (operation === 'first_add'){
$button.addClass('d-none');
$kanbanRecord.find('.dc-qty-controls').removeClass("d-none");
}
if (operation === 'add' || operation === 'first_add') {
newQuantity = newQuantity + 1;
}
if (operation === 'remove') {
newQuantity = newQuantity - 1;
}
// Update display optimistically
$quantityDisplay.text(newQuantity.toFixed(2));
try {
// Call server to update quantity
await $.ajax({
@ -139,22 +154,13 @@ async function handleQuantityChange($button, operation) {
throw info;
});
// Visual feedback - flash color based on operation
if (operation === 'add') {
$quantityDisplay.addClass('bg-success').removeClass('bg-secondary');
} else {
$quantityDisplay.addClass('bg-info').removeClass('bg-secondary');
}
setTimeout(() => {
$quantityDisplay.removeClass('bg-success bg-info').addClass('bg-secondary');
}, 300);
} catch (error) {
// Revert on error
$quantityDisplay.text(currentQuantity.toFixed(2));
$quantityDisplay.addClass('bg-danger').removeClass('bg-secondary');
// $quantityDisplay.addClass('bg-danger').removeClass('bg-secondary');
setTimeout(() => {
$quantityDisplay.removeClass('bg-danger').addClass('bg-secondary');
// $quantityDisplay.removeClass('bg-danger').addClass('bg-secondary');
}, 1000);
} finally {
// Re-enable buttons

View File

@ -4,34 +4,37 @@
<field name="model">product.template</field>
<field name="arch" type="xml">
<kanban edit="0" create="0" class="o_kanban_mobile o_cart_kanban">
<field name="id"/>
<field name="name"/>
<field name="_quantity"/>
<field name="id" />
<field name="name" />
<field name="_quantity" />
<templates>
<t t-name="kanban-box">
<div class="o_product_quantity d-flex flex-column justify-content-between"
style="min-height: 100px;width: 25%;">
<div class="o_kanban_image">
style="min-height: 100px;width: 25%;">
<div class="o_kanban_image" style="display: flex;width: 100%;justify-content: space-between;align-items: center;">
<img t-att-src="kanban_image('product.template', 'image_128', record.id.raw_value)"
alt="Product" class="o_image_64_contain"/>
alt="Product" class="o_image_64_contain" style="width: 100%;object-fit: cover;height: 100px;"/>
</div>
<h5 style="margin-top: 5px;text-align: center;">
<span>Amount:</span>
<field name="lst_price" widget="monetary" options="{'currency_field': 'currency_id'}" />
</h5>
<div class="oe_kanban_details p-2 d-flex">
<div class="o_kanban_record_top flex-column w-100 "
style="justify-content: space-between;">
<div class="o_kanban_record_title">
style="justify-content: space-between;">
<div class="o_kanban_record_title w-100" style="text-align: center;">
<strong>
<field name="name"/>
<field name="name" />
</strong>
</div>
<div class="d-flex w-100 justify-content-between">
<ul>
<!-- <ul>
<li>
<strong>
Price:
<field name="lst_price" widget="monetary"
options="{'currency_field': 'currency_id'}"/>
<strong> Amount: <field name="lst_price"
widget="monetary"
options="{'currency_field': 'currency_id'}" />
</strong>
</li>
</li> -->
<!-- <field name="currency_id" invisible="1"/> -->
<!-- <div> -->
@ -40,77 +43,51 @@
<!-- <field name="uom_id" class="ms-1" -->
<!-- groups="uom.group_uom"/> -->
<!-- </div> -->
</ul>
<!-- </ul> -->
</div>
<!-- <button t-if="record._quantity == 0"-->
<!-- <button
id="add_quantity"
class="btn btn-primary rounded-circle p-0 d-flex align-items-center justify-content-center"
style="width: 25px; height: 25px;" type="object"
name="add_quantity_button_so" string="ADD">
<i class="fa fa-plus fs-5" title="إضافة"/>
<div class="d-flex w-100 justify-content-center align-items-center mt-4">
</button> -->
<button class="btn btn-secondary" type="button"
name="add_quantity_button_so"
data-name="add_quantity_button_request"
title="إضافة منتج"
onclick="return window.__dc_first_add(this);">
<i class="fa fa-shopping-cart" />
<span>Add</span>
</button>
<!-- <button-->
<!-- id="add_quantity"-->
<!-- class="oe_kanban_button oe_dynamic_button btn btn-primary rounded-circle p-0 d-flex align-items-center justify-content-center"-->
<!-- style="width: 25px; height: 25px;" type="object"-->
<!-- name="add_quantity_button_so" string="ADD">-->
<!-- <i class="fa fa-plus fs-5" title="إضافة"/>-->
<!-- </button>-->
<!-- <t t-if="record._quantity == 1">
<span class="fa fa-plus fs-5">م الإضافة</span>
</t> -->
<!-- Quantity Controls: Minus, Display, Plus -->
<div class="d-flex align-items-center gap-2 dc-qty-controls">
<!-- Minus Button -->
<button
class="btn btn-light border rounded-circle p-0 d-flex align-items-center justify-content-center"
style="width: 28px; height: 28px;"
type="button"
name="remove_quantity_button_so"
title="تقليل الكمية"
onclick="return window.__dc_remove(this);">
<i class="fa fa-minus" style="font-size: 12px;"/>
</button>
<!-- Quantity Display -->
<span class="badge bg-secondary px-2 py-1 dc-qty-badge"
style="min-width: 35px; font-size: 14px; font-weight: bold;">
<field name="_quantity"/>
</span>
<!-- Plus Button -->
<button
class="btn btn-primary rounded-circle p-0 d-flex align-items-center justify-content-center"
style="width: 28px; height: 28px;"
type="button"
name="add_quantity_button_so"
title="إضافة"
onclick="return window.__dc_add(this);">
<i class="fa fa-plus" style="font-size: 12px;"/>
</button>
<div class="dc-qty-controls d-none">
<div class="input-group">
<div class="input-group-prepend">
<button
class="btn btn-primary"
type="button"
name="remove_quantity_button_so"
data-name="remove_quantity_button_so"
title="تقليل الكمية"
onclick="return window.__dc_remove(this);">
<i class="fa fa-minus" />
</button>
</div>
<div class="form-control dc-qty-badge">
<field name="_quantity" />
</div>
<div class="input-group-prepend">
<button
class="btn btn-primary"
type="button"
name="add_quantity_button_so"
data-name="add_quantity_button_so"
title="إضافة"
onclick="return window.__dc_add(this);">
<i class="fa fa-plus" />
</button>
</div>
</div>
</div>
</div>
<!-- <div name="_quantity" -->
<!-- class="h-100 ml-2 d-flex align-items-center o_product_quantity o_field_widget o_quick_editable" -->
<!-- style="z-index:1;align-items: center;"> -->
<!-- <button id="remove_quantity" -->
<!-- class="btn d-flex align-items-center justify-content-center o_qty_button btn-light text-muted" -->
<!-- type="object" name="remove_quantity_button_so"> -->
<!-- <i class="fa fa-minus center" title="Decrease" /> -->
<!-- </button> -->
<!-- <span style="font-size:1.5rem;" -->
<!-- t-attf-class="{{record.id.value}}" -->
<!-- onclick="change_input_so(this)"> -->
<!-- <field name="_quantity"></field> -->
<!-- </span> -->
<!-- <button id="add_quantity" -->
<!-- class="btn d-flex align-items-center justify-content-center o_qty_button btn-light text-muted" -->
<!-- type="object" name="add_quantity_button_so" string="ADD"> -->
<!-- &lt;!&ndash; <i class="fa fa-plus" title="Increase" />&ndash;&gt; -->
<!-- </button> -->
<!-- </div> -->
</div>
</div>
</div>
@ -119,6 +96,7 @@
</kanban>
</field>
</record>
<!-- Tree view for product.template with sponsorship button -->
<record id="view_product_template_tree_sponsorship" model="ir.ui.view">
<field name="name">product.template.tree.sponsorship</field>
@ -126,23 +104,24 @@
<field name="arch" type="xml">
<tree string="Products">
<header>
<button name="link_to_sponsorship" type="object" string="Link to Sponsorship" class="btn-primary"
icon="fa-link"/>
<button name="link_to_sponsorship" type="object" string="Link to Sponsorship"
class="btn-primary"
icon="fa-link" />
</header>
<field name="name"/>
<field name="donation_category"/>
<field name="list_price" string="Price"/>
<field name="name" />
<field name="donation_category" />
<field name="list_price" string="Price" />
</tree>
</field>
</record>
<record id="odex_takaful_product_template_form_view" model="ir.ui.view">
<field name="name">odex.takaful.product.template.form.view</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="inherit_id" ref="product.product_template_form_view" />
<field name="arch" type="xml">
<field name="uom_id" position="before">
<field name="payment_method_id" options="{'no_create': True}"/>
<field name="payment_method_id" options="{'no_create': True}" />
</field>
</field>
</record>
</odoo>
</odoo>