Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[IMP] PoS usability improvements #32870

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 2 additions & 20 deletions addons/point_of_sale/data/point_of_sale_data.xml
@@ -1,23 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<data noupdate="1">
<record id="seq_picking_type_posout" model="ir.sequence">
<field name="name">Picking POS</field>
<field name="prefix">POS</field>
<field name="padding">5</field>
<field name="company_id" eval="False"/>
</record>
</data>
<data noupdate="0">
<record id="picking_type_posout" model="stock.picking.type">
<field name="name">PoS Orders</field>
<field name="sequence_id" ref="seq_picking_type_posout"/>
<field name="default_location_src_id" ref="stock.stock_location_stock"/>
<field name="default_location_dest_id" ref="stock.stock_location_customers"/>
<field name="warehouse_id" eval="False"/>
<field name="code">outgoing</field>
</record>
</data>
<data noupdate="1">
<!-- After closing the PoS, open the dashboard menu -->
<record id="action_client_pos_menu" model="ir.actions.client">
Expand All @@ -26,6 +8,8 @@
<field name="params" eval="{'menu_id': ref('menu_point_root')}"/>
</record>

<function model="stock.warehouse" name="_create_missing_pos_picking_types"/>

<record id="product_category_pos" model="product.category">
<field name="parent_id" ref="product.product_category_1"/>
<field name="name">PoS</field>
Expand All @@ -41,7 +25,6 @@

<record model="pos.config" id="pos_config_main">
<field name="name">Shop</field>
<field name="picking_type_id" ref="picking_type_posout"/>
<field name="barcode_nomenclature_id" ref="barcodes.default_barcode_nomenclature"/>
</record>

Expand Down Expand Up @@ -72,4 +55,3 @@
</record>
</data>
</odoo>

1 change: 1 addition & 0 deletions addons/point_of_sale/models/__init__.py
Expand Up @@ -14,3 +14,4 @@
from . import res_partner
from . import res_company
from . import res_config_settings
from . import stock_warehouse
26 changes: 8 additions & 18 deletions addons/point_of_sale/models/pos_config.py
Expand Up @@ -39,6 +39,9 @@ class PosConfig(models.Model):
_name = 'pos.config'
_description = 'Point of Sale Configuration'

def _default_picking_type_id(self):
return self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1).pos_type_id.id

def _default_sale_journal(self):
journal = self.env.ref('point_of_sale.pos_sale_journal', raise_if_not_found=False)
if journal and journal.sudo().company_id == self.env.company:
Expand All @@ -51,9 +54,6 @@ def _default_invoice_journal(self):
def _default_pricelist(self):
return self.env['product.pricelist'].search([('currency_id', '=', self.env.company.currency_id.id)], limit=1)

def _get_default_location(self):
return self.env['stock.warehouse'].search([('company_id', '=', self.env.company.id)], limit=1).lot_stock_id

def _get_group_pos_manager(self):
return self.env.ref('point_of_sale.group_pos_manager')

Expand All @@ -70,11 +70,12 @@ def _compute_default_customer_html(self):
'account.journal', 'pos_config_journal_rel',
'pos_config_id', 'journal_id', string='Available Payment Methods',
domain="[('journal_user', '=', True ), ('type', 'in', ['bank', 'cash'])]",)
picking_type_id = fields.Many2one('stock.picking.type', string='Operation Type')
picking_type_id = fields.Many2one(
'stock.picking.type',
string='Operation Type',
default=_default_picking_type_id,
domain="[('code', '=', 'outgoing'), ('warehouse_id.company_id', '=', company_id)]")
bouvyd marked this conversation as resolved.
Show resolved Hide resolved
use_existing_lots = fields.Boolean(related='picking_type_id.use_existing_lots', readonly=False)
stock_location_id = fields.Many2one(
'stock.location', string='Stock Location',
domain=[('usage', '=', 'internal')], required=True, default=_get_default_location)
journal_id = fields.Many2one(
'account.journal', string='Sales Journal',
domain=[('type', '=', 'sale')],
Expand Down Expand Up @@ -220,11 +221,6 @@ def _compute_current_session_user(self):
pos_config.pos_session_state = False
pos_config.pos_session_duration = 0

@api.constrains('company_id', 'stock_location_id')
def _check_company_location(self):
if self.stock_location_id.company_id and self.stock_location_id.company_id.id != self.company_id.id:
raise ValidationError(_("The stock location and the point of sale must belong to the same company."))

@api.constrains('company_id', 'journal_id')
def _check_company_journal(self):
if self.journal_id and self.journal_id.company_id.id != self.company_id.id:
Expand Down Expand Up @@ -267,11 +263,6 @@ def _onchange_module_account(self):
if self.module_account:
self.invoice_journal_id = self.env.ref('point_of_sale.pos_sale_journal')

@api.onchange('picking_type_id')
def _onchange_picking_type_id(self):
if self.picking_type_id.default_location_src_id.usage == 'internal' and self.picking_type_id.default_location_dest_id.usage == 'customer':
self.stock_location_id = self.picking_type_id.default_location_src_id.id

@api.onchange('use_pricelist')
def _onchange_use_pricelist(self):
"""
Expand Down Expand Up @@ -441,7 +432,6 @@ def open_session_cb(self):
"""
self.ensure_one()
if not self.current_session_id:
self._check_company_location()
self._check_company_journal()
self._check_company_invoice_journal()
self._check_company_payment()
Expand Down
4 changes: 2 additions & 2 deletions addons/point_of_sale/models/pos_order.py
Expand Up @@ -573,7 +573,7 @@ def _default_pricelist(self):
picking_type_id = fields.Many2one('stock.picking.type', related='session_id.config_id.picking_type_id', string="Operation Type", readonly=False)
location_id = fields.Many2one(
comodel_name='stock.location',
related='session_id.config_id.stock_location_id',
related='picking_id.location_id',
string="Location", store=True,
readonly=True,
)
Expand Down Expand Up @@ -793,7 +793,7 @@ def create_picking(self):
order_picking = Picking
return_picking = Picking
moves = Move
location_id = order.location_id.id
location_id = picking_type.default_location_src_id.id
if order.partner_id:
destination_id = order.partner_id.property_stock_customer.id
else:
Expand Down
17 changes: 17 additions & 0 deletions addons/point_of_sale/models/pos_session.py
Expand Up @@ -102,6 +102,7 @@ def _confirm_orders(self):
readonly=True,
string='Available Payment Methods')
order_ids = fields.One2many('pos.order', 'session_id', string='Orders')
order_count = fields.Integer(compute='_compute_order_count')
statement_ids = fields.One2many('account.bank.statement', 'pos_session_id', string='Bank Statement', readonly=True)
picking_count = fields.Integer(compute='_compute_picking_count')
rescue = fields.Boolean(string='Recovery Session',
Expand All @@ -111,6 +112,13 @@ def _confirm_orders(self):

_sql_constraints = [('uniq_name', 'unique(name)', "The name of this POS Session must be unique !")]

@api.multi
def _compute_order_count(self):
orders_data = self.env['pos.order'].read_group([('session_id', 'in', self.ids)], ['session_id'], ['session_id'])
sessions_data = {order_data['session_id'][0]: order_data['session_id_count'] for order_data in orders_data}
for session in self:
session.order_count = sessions_data.get(session.id, 0)

@api.multi
def _compute_picking_count(self):
for pos in self:
Expand Down Expand Up @@ -345,6 +353,15 @@ def open_cashbox(self):

return action

def action_view_order(self):
return {
'name': _('Orders'),
'res_model': 'pos.order',
'view_mode': 'tree,form',
'type': 'ir.actions.act_window',
'domain': [('session_id', 'in', self.ids)],
}

@api.model
def _alert_old_session(self):
# If the session is open for more then one week,
Expand Down
48 changes: 48 additions & 0 deletions addons/point_of_sale/models/stock_warehouse.py
@@ -0,0 +1,48 @@
# -*- coding: utf-8 -*-

from odoo import models, fields, api, _


class Warehouse(models.Model):
_inherit = "stock.warehouse"

pos_type_id = fields.Many2one('stock.picking.type', string="Point of Sale Operation Type")

def _get_sequence_values(self):
sequence_values = super(Warehouse, self)._get_sequence_values()
sequence_values.update({
'pos_type_id': {
'name': self.name + ' ' + _('Picking POS'),
'prefix': self.code + '/POS/',
'padding': 5,
'company_id': self.company_id.id,
}
})
return sequence_values

def _get_picking_type_update_values(self):
picking_type_update_values = super(Warehouse, self)._get_picking_type_update_values()
picking_type_update_values.update({
'pos_type_id': {'default_location_src_id': self.lot_stock_id.id}
})
return picking_type_update_values

def _get_picking_type_create_values(self, max_sequence):
picking_type_create_values, max_sequence = super(Warehouse, self)._get_picking_type_create_values(max_sequence)
picking_type_create_values.update({
'pos_type_id': {
'name': _('PoS Orders'),
'code': 'outgoing',
'default_location_src_id': self.lot_stock_id.id,
'default_location_dest_id': self.env.ref('stock.stock_location_customers').id,
bouvyd marked this conversation as resolved.
Show resolved Hide resolved
'sequence': max_sequence + 1,
}
})
return picking_type_create_values, max_sequence + 2

@api.model
def _create_missing_pos_picking_types(self):
warehouses = self.env['stock.warehouse'].search([('pos_type_id', '=', False)])
for warehouse in warehouses:
new_vals = warehouse._create_or_update_sequences_and_picking_types()
warehouse.write(new_vals)
10 changes: 0 additions & 10 deletions addons/point_of_sale/static/src/js/models.js
Expand Up @@ -51,7 +51,6 @@ exports.PosModel = Backbone.Model.extend({
this.company_logo = null;
this.company_logo_base64 = '';
this.currency = null;
this.shop = null;
this.company = null;
this.user = null;
this.users = [];
Expand Down Expand Up @@ -278,11 +277,6 @@ exports.PosModel = Backbone.Model.extend({
self.pos_session.sequence_number = Math.max(self.pos_session.sequence_number, orders[i].data.sequence_number+1);
}
},
},{
model: 'stock.location',
fields: [],
ids: function(self){ return [self.config.stock_location_id[0]]; },
loaded: function(self, locations){ self.shop = locations[0]; },
},{
model: 'product.pricelist',
fields: ['name', 'display_name', 'discount_policy'],
Expand Down Expand Up @@ -2243,7 +2237,6 @@ exports.Order = Backbone.Model.extend({
var client = this.get('client');
var cashier = this.pos.get_cashier();
var company = this.pos.company;
var shop = this.pos.shop;
var date = new Date();

function is_xml(subreceipt){
Expand Down Expand Up @@ -2305,9 +2298,6 @@ exports.Order = Backbone.Model.extend({
phone: company.phone,
logo: this.pos.company_logo_base64,
},
shop:{
name: shop.name,
},
currency: this.pos.currency,
};

Expand Down
18 changes: 4 additions & 14 deletions addons/point_of_sale/views/pos_config_view.xml
Expand Up @@ -457,24 +457,14 @@
<div class="o_setting_right_pane">
<label for="picking_type_id" string="Operation Type"/>
<div class="text-muted">
Operation type used to record product pickings
Operation type used to record product pickings <br/>
Products will be taken from the default source location of this operation type
</div>
<div class="content-group mt16">
<field name="picking_type_id" required="1"/>
</div>
</div>
</div>
<div class="col-12 col-lg-6 o_setting_box" groups="stock.group_stock_multi_locations">
<div class="o_setting_right_pane">
<label for="stock_location_id"/>
<div class="text-muted">
Stock location used for the inventory
</div>
<div>
<field name="stock_location_id" options="{'no_create': True}"/>
</div>
</div>
</div>
</div>
<h2>Accounting</h2>
<div class="row mt16 o_settings_container" id="accounting_section">
Expand Down Expand Up @@ -509,7 +499,7 @@
<field name="arch" type="xml">
<tree string="Point of Sale Configuration">
<field name="name" />
<field name="stock_location_id" options="{'no_create': True}" groups="stock.group_stock_multi_locations"/>
<field name="picking_type_id"/>
</tree>
</field>
</record>
Expand All @@ -521,7 +511,7 @@
<search string="Point of Sale Config">
<field name="name"/>
<filter string="Inactive" name="inactive" domain="[('active', '=', False)]" />
<field name="stock_location_id" groups="stock.group_stock_multi_locations" />
<field name="picking_type_id" />
</search>
</field>
</record>
Expand Down
2 changes: 1 addition & 1 deletion addons/point_of_sale/views/pos_order_view.xml
Expand Up @@ -210,7 +210,7 @@
</field>
</record>

<menuitem id="menu_point_ofsale" parent="menu_point_of_sale" action="action_pos_pos_form" sequence="1" groups="group_pos_manager,group_pos_user"/>
<menuitem id="menu_point_ofsale" parent="menu_point_of_sale" action="action_pos_pos_form" sequence="2" groups="group_pos_manager,group_pos_user"/>

<record id="view_pos_order_line" model="ir.ui.view">
<field name="name">pos.order.line.tree</field>
Expand Down
8 changes: 7 additions & 1 deletion addons/point_of_sale/views/pos_session_view.xml
Expand Up @@ -63,6 +63,12 @@
type="object" context="{'balance': 'end'}">
<span class="o_stat_text">Set Closing Balance</span>
</button>
<button name="action_view_order"
class="oe_stat_button"
icon="fa-shopping-basket"
type="object">
<field name="order_count" widget="statinfo" string="Orders"/>
</button>
<button class="oe_stat_button" name="action_stock_picking" type="object" icon="fa-arrows-v" attrs="{'invisible':[('picking_count', '=', 0)]}">
<field name="picking_count" widget="statinfo" string="Picking Errors"/>
</button>
Expand Down Expand Up @@ -234,6 +240,6 @@
id="menu_pos_session_all"
parent="menu_point_of_sale"
action="action_pos_session"
sequence="2"
sequence="1"
groups="group_pos_manager"/>
</odoo>
1 change: 0 additions & 1 deletion addons/pos_restaurant/data/pos_restaurant_demo.xml
Expand Up @@ -195,7 +195,6 @@
<!-- Pos Config -->
<record model="pos.config" id="pos_config_restaurant">
<field name="name">Bar</field>
<field name="picking_type_id" ref="point_of_sale.picking_type_posout"/>
<field name="barcode_nomenclature_id" ref="barcodes.default_barcode_nomenclature"/>
<field name="module_pos_restaurant">True</field>
<field name="is_table_management">True</field>
Expand Down
5 changes: 3 additions & 2 deletions addons/pos_sale/models/pos_config.py
Expand Up @@ -2,16 +2,17 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from odoo import fields, models
from odoo.exceptions import AccessError


class PosConfig(models.Model):
_inherit = 'pos.config'

def _get_default_pos_team(self):
try:
team = self.env.ref('sales_team.pos_sales_team')
team = self.env.ref('sales_team.pos_sales_team', raise_if_not_found=False)
return team if team.active else None
except ValueError:
except AccessError:
return None

crm_team_id = fields.Many2one(
Expand Down