mirror of
https://github.com/bringout/oca-pos.git
synced 2026-04-24 01:22:05 +02:00
Move all OCA POS modules from oca-technical to dedicated oca-pos submodule
Reorganized 74 POS-related modules for better structure: - Moved all odoo-bringout-oca-pos-* packages from packages/oca-technical/ - Now organized in dedicated packages/oca-pos/ submodule - Includes payment, receipt, loyalty, order, product, and partner modules - Maintains all module functionality while improving project organization This creates a cleaner separation between general technical modules and Point of Sale specific functionality. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
3791451dc1
commit
377f346a99
2675 changed files with 93308 additions and 0 deletions
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
Copyright (C) 2022-Today GRAP (http://www.grap.coop)
|
||||
@author Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
||||
*/
|
||||
|
||||
.pos .product .membership-forbidden-tag {
|
||||
color: white;
|
||||
background: rgba(255, 76, 76, 0.5);
|
||||
border-radius: 2px;
|
||||
padding: 1px 4px;
|
||||
}
|
||||
|
||||
.product-info-popup .allowed-membership-category {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
vertical-align: top;
|
||||
max-width: 200px;
|
||||
color: inherit;
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
odoo.define("pos_membership_extension.ProductItem", function (require) {
|
||||
"use strict";
|
||||
|
||||
const ProductItem = require("point_of_sale.ProductItem");
|
||||
const Registries = require("point_of_sale.Registries");
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
const OverloadProductItem = (ProductItem) =>
|
||||
// eslint-disable-next-line no-shadow
|
||||
class OverloadProductItem extends ProductItem {
|
||||
get membership_allowed() {
|
||||
var res = this.props.product.get_membership_allowed(
|
||||
this.env.pos.get_order().partner
|
||||
);
|
||||
return res;
|
||||
}
|
||||
};
|
||||
|
||||
Registries.Component.extend(ProductItem, OverloadProductItem);
|
||||
|
||||
return ProductItem;
|
||||
});
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
odoo.define("pos_membership_extension.ProductScreen", function (require) {
|
||||
"use strict";
|
||||
|
||||
const ProductScreen = require("point_of_sale.ProductScreen");
|
||||
const Registries = require("point_of_sale.Registries");
|
||||
|
||||
// eslint-disable-next-line no-shadow
|
||||
const OverloadProductScreen = (ProductScreen) =>
|
||||
// eslint-disable-next-line no-shadow
|
||||
class OverloadProductScreen extends ProductScreen {
|
||||
async _getAddProductOptions(product) {
|
||||
var self = this;
|
||||
if (!product.get_membership_allowed(this.env.pos.get_order().partner)) {
|
||||
await this.showPopup("ErrorPopup", {
|
||||
title: self.env._t("Incorrect Membership"),
|
||||
body: self.env._t(
|
||||
"Please select a customer that belong to one of the related membership categories."
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
return await super._getAddProductOptions(...arguments);
|
||||
}
|
||||
};
|
||||
|
||||
Registries.Component.extend(ProductScreen, OverloadProductScreen);
|
||||
|
||||
return ProductScreen;
|
||||
});
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
odoo.define("pos_membership_extension.models", function (require) {
|
||||
"use strict";
|
||||
|
||||
const {Order, Product} = require("point_of_sale.models");
|
||||
|
||||
var core = require("web.core");
|
||||
|
||||
var {Gui} = require("point_of_sale.Gui");
|
||||
const Registries = require("point_of_sale.Registries");
|
||||
|
||||
var _t = core._t;
|
||||
|
||||
const OverloadProduct = (OriginalProduct) =>
|
||||
class extends OriginalProduct {
|
||||
/**
|
||||
* Return if it's allowed to sell the product to the partner.
|
||||
*
|
||||
* @param {partner} partner to test. (can be undefined)
|
||||
* @returns {Boolean} True if the sell is allowed, false otherwise.
|
||||
*/
|
||||
get_membership_allowed(partner) {
|
||||
// No categories means no restriction
|
||||
if (this.allowed_membership_category_ids.length === 0) {
|
||||
return true;
|
||||
}
|
||||
// If categories are set, but no partner, sell is forbidden in any case
|
||||
if (!partner) {
|
||||
return false;
|
||||
}
|
||||
var common_categories = this.allowed_membership_category_ids.filter(
|
||||
function (categ) {
|
||||
return partner.membership_category_ids.indexOf(categ) !== -1;
|
||||
}
|
||||
);
|
||||
return common_categories.length !== 0;
|
||||
}
|
||||
};
|
||||
Registries.Model.extend(Product, OverloadProduct);
|
||||
|
||||
const OverloadOrder = (OriginalOrder) =>
|
||||
class extends OriginalOrder {
|
||||
/**
|
||||
* Overloaded function.
|
||||
* Check if the product of the order lines are allowed by the
|
||||
* new selected partner.
|
||||
* If not, remove according lines and raise a PopUp Error to
|
||||
* inform the cashier of the removal.
|
||||
* @param {partner} partner to set to the order. (can be undefined)
|
||||
* @returns {Boolean} In any case, return the result of the super function.
|
||||
*/
|
||||
set_partner(partner) {
|
||||
var bad_product_list = [];
|
||||
var i = this.orderlines.length;
|
||||
while (i--) {
|
||||
var orderline = this.orderlines[i];
|
||||
if (!orderline.product.get_membership_allowed(partner)) {
|
||||
bad_product_list.push(orderline.product.display_name);
|
||||
this.orderlines.splice(i, 1);
|
||||
}
|
||||
}
|
||||
if (bad_product_list.length !== 0) {
|
||||
var bad_product_text = bad_product_list.join(", ");
|
||||
Gui.showPopup("ErrorPopup", {
|
||||
title: _t("Order Line Removal"),
|
||||
body: _t(
|
||||
`The following lines has been removed, as the product cannot be sold to this partner: ${bad_product_text}`
|
||||
),
|
||||
});
|
||||
}
|
||||
|
||||
return super.set_partner(...arguments);
|
||||
}
|
||||
};
|
||||
|
||||
Registries.Model.extend(Order, OverloadOrder);
|
||||
});
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2022-Today GRAP (http://www.grap.coop)
|
||||
@author Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
||||
-->
|
||||
<templates id="template" xml:space="preserve">
|
||||
|
||||
<t
|
||||
t-name="ProductInfoPopup"
|
||||
t-inherit="point_of_sale.ProductInfoPopup"
|
||||
t-inherit-mode="extension"
|
||||
owl="1"
|
||||
>
|
||||
<xpath
|
||||
expr="//div[hasclass('section-product-info-title')]/div[1]/span[last()]"
|
||||
position="after"
|
||||
>
|
||||
<span
|
||||
t-if="productInfo.allowed_membership_categories.length"
|
||||
>Membership Categories:
|
||||
<t
|
||||
t-foreach="productInfo.allowed_membership_categories"
|
||||
t-as="category"
|
||||
t-key="category.name"
|
||||
>
|
||||
<t t-esc="category.name" />
|
||||
<t
|
||||
t-if="category_index lt productInfo.allowed_membership_categories.length - 1"
|
||||
>, </t>
|
||||
</t>
|
||||
</span>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!--
|
||||
Copyright (C) 2022-Today GRAP (http://www.grap.coop)
|
||||
@author Sylvain LE GAL (https://twitter.com/legalsylvain)
|
||||
License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html
|
||||
-->
|
||||
<templates id="template" xml:space="preserve">
|
||||
|
||||
<t
|
||||
t-name="ProductItem"
|
||||
t-inherit="point_of_sale.ProductItem"
|
||||
t-inherit-mode="extension"
|
||||
owl="1"
|
||||
>
|
||||
<xpath expr="//span[hasclass('price-tag')]" position="inside">
|
||||
|
||||
<i
|
||||
role="img"
|
||||
class="membership-forbidden-tag fa fa-ban"
|
||||
t-if="!membership_allowed"
|
||||
title="This product can not be sold because of membership rules"
|
||||
/>
|
||||
</xpath>
|
||||
</t>
|
||||
|
||||
</templates>
|
||||
Loading…
Add table
Add a link
Reference in a new issue