Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pos_second_uom/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import models
19 changes: 19 additions & 0 deletions pos_second_uom/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "POS Second UoM",
"description": """
This module allows cashier to sell product in second unit of measure
""",
"depends": [
"product",
"point_of_sale",
],
"data": ["views/product_template.xml"],
"assets": {
"point_of_sale._assets_pos": [
"pos_second_uom/static/src/**/*",
]
},
"license": "LGPL-3",
"application": True,
"installable": True,
}
1 change: 1 addition & 0 deletions pos_second_uom/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import product_template
31 changes: 31 additions & 0 deletions pos_second_uom/models/product_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from odoo import fields, models, api


class ProductTemplate(models.Model):
_inherit = "product.template"

uom_category_id = fields.Many2one(
comodel_name="uom.uom",
string="UoM Category",
related="uom_id.category_id",
store=True,
)

pos_secondary_uom_id = fields.Many2one(
comodel_name="uom.uom",
string="Secondary Unit of Measure",
domain="[('category_id', '=', uom_category_id), ('id', '!=', uom_id)]",
)

@api.onchange("uom_id")
def _onchange_uom_id(self):
self.pos_secondary_uom_id = False


class ProductProduct(models.Model):
_name = "product.product"
_inherit = ["product.product"]

@api.model
def _load_pos_data_fields(self, config_id):
return super()._load_pos_data_fields(config_id) + ["pos_secondary_uom_id"]
45 changes: 45 additions & 0 deletions pos_second_uom/static/src/js/add_quantity.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/** @odoo-module **/

import { Component, useState } from "@odoo/owl";
import { Dialog } from "@web/core/dialog/dialog";
import { usePos } from "@point_of_sale/app/store/pos_hook";


export class SecondaryUomDialog extends Component {
static template = "pos_secondary_uom.SecondaryUomDialog";
static components = { Dialog };

setup() {
this.pos = usePos();
this.state = useState({ quantity: 1 });

this.orderline = this.props.orderline;
const uomIds = this.orderline.product_id.uom_id.category_id.uom_ids;

this.baseUom = uomIds[0];
this.secondaryUom = uomIds[1];
this.conversionRatio = 1;
if (this.secondaryUom && this.baseUom) {
const secondaryFactor = this.secondaryUom.factor;
const baseFactor = this.baseUom.factor;
this.conversionRatio = baseFactor / secondaryFactor;
}
}

confirm() {
const enteredQty = parseFloat(this.state.quantity);
if (isNaN(enteredQty) || enteredQty <= 0) {
this.pos.env.services.notification.add("Enter a valid quantity", { type: "warning" });
return;
}

const baseQty = enteredQty * this.conversionRatio;
this.orderline.set_quantity(baseQty);
this.orderline.uom_id = this.secondaryUom;
this.props.close();
}

cancel() {
this.props.close();
}
}
40 changes: 40 additions & 0 deletions pos_second_uom/static/src/js/add_quantity.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates id="template" xml:space="preserve">

<t t-name="pos_secondary_uom.SecondaryUomDialog">
<div class="modal-backdrop show"></div>
<div class="modal d-block" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content p-4">
<div class="modal-header">
<h5 class="modal-title">Enter Quantity in Dozen</h5>
<button type="button" class="btn-close" aria-label="Close" t-on-click="cancel"></button>
</div>
<div class="modal-body">
<div >
<label for="secondary-uom-input">Quantity (Secondary UoM)</label>
<input
id="secondary-uom-input"
type="number"
t-model="state.quantity"
/>
</div>
</div>
<div class="modal-footer d-flex justify-end mt-3">
<button type="button" class="btn btn-primary me-2" t-on-click="confirm">Confirm</button>
<button type="button" class="btn btn-secondary" t-on-click="cancel">Discard</button>
</div>
</div>
</div>
</div>
</t>

<t t-name="pos_secondary_uom.ControlButtons" t-inherit="point_of_sale.ControlButtons" t-inherit-mode="extension">
<xpath expr="//SelectPartnerButton" position="after">
<button t-if="this.pos.selectedOrder.get_selected_orderline()?.product_id.pos_secondary_uom_id !== undefined and !currentOrder?.is_empty() and pos.get_order()?.uiState.selected_orderline_uuid" class="btn btn-light btn-lg lh-lg text-truncate w-auto" t-on-click="openSecondaryUomDialog">
Add Quantity
</button>
</xpath>
</t>

</templates>
23 changes: 23 additions & 0 deletions pos_second_uom/static/src/js/control_button.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@

import { patch } from "@web/core/utils/patch";
import { ControlButtons } from "@point_of_sale/app/screens/product_screen/control_buttons/control_buttons";
import { SecondaryUomDialog } from "./add_quantity";


patch(ControlButtons.prototype, {
async openSecondaryUomDialog() {
const order = this.pos.get_order();
const orderline = order.get_selected_orderline();

if (!orderline.product_id.uom_id.category_id.uom_ids[1]) {
this.env.services.notification.add("Select a product with a secondary UoM first.", {
type: "warning",
});
return;
}

this.dialog.add(SecondaryUomDialog, {
orderline,
});
},
});
Empty file.
12 changes: 12 additions & 0 deletions pos_second_uom/views/product_template.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<odoo>
<record id="view_product_template_form_secondary_uom" model="ir.ui.view">
<field name="name">product.template.form.secondary.uom</field>
<field name="model">product.template</field>
<field name="inherit_id" ref="product.product_template_form_view"/>
<field name="arch" type="xml">
<xpath expr="//group[@name='pos']" position="inside">
<field name="pos_secondary_uom_id"/>
</xpath>
</field>
</record>
</odoo>