[FIX] point_of_sale: disabled commercial fields in child partner
Prior to this commit, a user was able to modify the commercial fields of a partner in the POS. This is not wanted and not possible in the backend. This commit adapts it to the backend behavior. closes odoo/odoo#146475 X-original-commit: 0c55915172f06864c6f29d59d3057fbe0ff42bb5 Related: odoo/enterprise#52885 Signed-off-by: Robin Heinz (rhe) <rhe@odoo.com> Signed-off-by: Adrien Guilliams (adgu) <adgu@odoo.com>
This commit is contained in:
@@ -1686,6 +1686,7 @@ class PosSession(models.Model):
|
||||
loaded_data['pos_has_valid_product'] = self._pos_has_valid_product()
|
||||
loaded_data['pos_special_products_ids'] = self.env['pos.config']._get_special_products().ids
|
||||
loaded_data['open_orders'] = self.env['pos.order'].search([('session_id', '=', self.id), ('state', '=', 'draft')]).export_for_ui()
|
||||
loaded_data['partner_commercial_fields'] = self.env['res.partner']._commercial_fields()
|
||||
|
||||
@api.model
|
||||
def _pos_ui_models_to_load(self):
|
||||
|
||||
+7
@@ -139,4 +139,11 @@ export class PartnerDetailsEdit extends Component {
|
||||
img.src = url;
|
||||
});
|
||||
}
|
||||
|
||||
isFieldCommercialAndPartnerIsChild(field) {
|
||||
return (
|
||||
this.pos.isChildPartner(this.props.partner) &&
|
||||
this.pos.partner_commercial_fields.includes(field)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -21,3 +21,8 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.partner-details input:disabled{
|
||||
color: #999999; // Lighter text color
|
||||
border-color: #cccccc; // Lighter border color
|
||||
}
|
||||
|
||||
+13
-6
@@ -19,13 +19,20 @@
|
||||
<t t-foreach="['Street', 'City', 'Zip', 'Email', 'Phone', 'Mobile', 'Barcode' ]" t-as="item" t-key="item">
|
||||
<div class="partner-detail col">
|
||||
<label class="form-label label" t-attf-for="{{item}}" t-esc="item"/>
|
||||
<input class="detail form-control" t-attf-id="{{item}}" t-attf-name="{{item}}" t-model="changes[item.toLowerCase()]" t-attf-placeholder="{{item}}" t-att-class="{'border-danger': missingFields.includes(item.toLowerCase())}" />
|
||||
<input
|
||||
class="detail form-control"
|
||||
t-attf-id="{{item}}"
|
||||
t-attf-name="{{item}}"
|
||||
t-model="changes[item.toLowerCase()]"
|
||||
t-attf-placeholder="{{item}}"
|
||||
t-att="{'disabled': isFieldCommercialAndPartnerIsChild(item)}"
|
||||
t-att-class="{'border-danger': missingFields.includes(item.toLowerCase())}" />
|
||||
</div>
|
||||
</t>
|
||||
|
||||
<div class="partner-detail col">
|
||||
<label class="form-label label" for="state">State</label>
|
||||
<select class="detail form-select" id="state" name="state_id" t-model="changes.state_id" t-att-class="{'border-danger': missingFields.includes('state_id')}">
|
||||
<select class="detail form-select" id="state" name="state_id" t-model="changes.state_id" t-att="{'disabled': isFieldCommercialAndPartnerIsChild('state_id')}" t-att-class="{'border-danger': missingFields.includes('state_id')}">
|
||||
<option value="">None</option>
|
||||
<t t-foreach="pos.states" t-as="state" t-key="state.id">
|
||||
<option t-if="changes.country_id == state.country_id[0]" t-att-value="state.id">
|
||||
@@ -36,7 +43,7 @@
|
||||
</div>
|
||||
<div class="partner-detail col">
|
||||
<label class="form-label label" for="country">Country</label>
|
||||
<select class="detail form-select" id="country" name="country_id" t-model="changes.country_id" t-att-class="{'border-danger': missingFields.includes('country_id')}">
|
||||
<select class="detail form-select" id="country" name="country_id" t-model="changes.country_id" t-att="{'disabled': isFieldCommercialAndPartnerIsChild('country_id')}" t-att-class="{'border-danger': missingFields.includes('country_id')}">
|
||||
<option value="">None</option>
|
||||
<t t-foreach="pos.countries" t-as="country" t-key="country.id">
|
||||
<option t-att-value="country.id">
|
||||
@@ -47,7 +54,7 @@
|
||||
</div>
|
||||
<div class="partner-detail col">
|
||||
<label class="form-label label" for="language">Language</label>
|
||||
<select class="detail form-select" id="language" name="lang" t-model="changes.lang" t-att-class="{'border-danger': missingFields.includes('lang')}">
|
||||
<select class="detail form-select" id="language" name="lang" t-model="changes.lang" t-att="{'disabled': isFieldCommercialAndPartnerIsChild('lang')}" t-att-class="{'border-danger': missingFields.includes('lang')}">
|
||||
<t t-foreach="pos.langs" t-as="lang" t-key="lang.id">
|
||||
<option t-att-value="lang.code" t-att-selected="changes.lang ? ((lang.code === changes.lang) ? true : undefined) : lang.code === pos.user.lang? true : undefined">
|
||||
<t t-esc="lang.name" />
|
||||
@@ -57,7 +64,7 @@
|
||||
</div>
|
||||
<div t-if="pos.pricelists.length gt 1" class="partner-detail col">
|
||||
<label class="form-label label" for="pricelist">Pricelist</label>
|
||||
<select class="detail form-select" id="pricelist" name="property_product_pricelist" t-model="changes.property_product_pricelist" t-att-class="{'border-danger': missingFields.includes('property_product_pricelist')}">
|
||||
<select class="detail form-select" id="pricelist" name="property_product_pricelist" t-model="changes.property_product_pricelist" t-att="{'disabled': isFieldCommercialAndPartnerIsChild('property_product_pricelist')}" t-att-class="{'border-danger': missingFields.includes('property_product_pricelist')}">
|
||||
<t t-foreach="pos.pricelists" t-as="pricelist" t-key="pricelist.id">
|
||||
<option t-att-value="pricelist.id" t-att-selected="props.partner.property_product_pricelist ? (pricelist.id === props.partner.property_product_pricelist[0] ? true : undefined) : pricelist.id === pos.default_pricelist.id ? true : undefined">
|
||||
<t t-esc="pricelist.display_name" />
|
||||
@@ -67,7 +74,7 @@
|
||||
</div>
|
||||
<div class="partner-detail col">
|
||||
<label class="form-label label" for="vat">Tax ID</label>
|
||||
<input class="detail vat form-control" id="vat" name="vat" t-model="changes.vat" t-att-class="{'border-danger': missingFields.includes('vat')}" />
|
||||
<input class="detail vat form-control" id="vat" name="vat" t-model="changes.vat" t-att="{'disabled': isFieldCommercialAndPartnerIsChild('vat')}" t-att-class="{'border-danger': missingFields.includes('vat')}" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -279,6 +279,7 @@ export class PosStore extends Reactive {
|
||||
this.base_url = loadedData["base_url"];
|
||||
this.pos_has_valid_product = loadedData["pos_has_valid_product"];
|
||||
this.db.addProductIdsToNotDisplay(loadedData["pos_special_products_ids"]);
|
||||
this.partner_commercial_fields = loadedData["partner_commercial_fields"];
|
||||
await this._loadPosPrinters(loadedData["pos.printer"]);
|
||||
this.open_orders_json = loadedData["open_orders"];
|
||||
}
|
||||
@@ -665,7 +666,9 @@ export class PosStore extends Reactive {
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!missingProductIds.size) return;
|
||||
if (!missingProductIds.size) {
|
||||
return;
|
||||
}
|
||||
const products = await this.orm.call(
|
||||
"pos.session",
|
||||
"get_pos_ui_product_product_by_params",
|
||||
@@ -675,13 +678,15 @@ export class PosStore extends Reactive {
|
||||
this._loadProductProduct(products);
|
||||
}
|
||||
async _loadMissingPricelistItems(products) {
|
||||
if(!products.length) return;
|
||||
const product_tmpl_ids = products.map(product => product.product_tmpl_id[0]);
|
||||
const product_ids = products.map(product => product.id);
|
||||
if (!products.length) {
|
||||
return;
|
||||
}
|
||||
const product_tmpl_ids = products.map((product) => product.product_tmpl_id[0]);
|
||||
const product_ids = products.map((product) => product.id);
|
||||
|
||||
const pricelistItems = await this.orm.call(
|
||||
'pos.session',
|
||||
'get_pos_ui_product_pricelist_item_by_product',
|
||||
"pos.session",
|
||||
"get_pos_ui_product_pricelist_item_by_product",
|
||||
[odoo.pos_session_id, product_tmpl_ids, product_ids]
|
||||
);
|
||||
|
||||
@@ -691,9 +696,9 @@ export class PosStore extends Reactive {
|
||||
// E.g. The order in the items should be: [product-pricelist-item, product-template-pricelist-item, category-pricelist-item, global-pricelist-item].
|
||||
// for reference check order of the Product Pricelist Item model
|
||||
for (const pricelist of this.pricelists) {
|
||||
const itemIds = new Set(pricelist.items.map(item => item.id));
|
||||
const itemIds = new Set(pricelist.items.map((item) => item.id));
|
||||
|
||||
const _pricelistItems = pricelistItems.filter(item => {
|
||||
const _pricelistItems = pricelistItems.filter((item) => {
|
||||
return item.pricelist_id[0] === pricelist.id && !itemIds.has(item.id);
|
||||
});
|
||||
pricelist.items = [..._pricelistItems, ...pricelist.items];
|
||||
@@ -1945,6 +1950,10 @@ export class PosStore extends Reactive {
|
||||
header: this.config.receipt_header,
|
||||
};
|
||||
}
|
||||
|
||||
isChildPartner(partner) {
|
||||
return partner.parent_name;
|
||||
}
|
||||
}
|
||||
|
||||
PosStore.prototype.electronic_payment_interfaces = {};
|
||||
|
||||
Reference in New Issue
Block a user