[IMP] PoS backend

bzr revid: fp@tinyerp.com-20120809212311-q2b86eww9ppvdv8s
This commit is contained in:
Fabien Pinckaers 2012-08-09 23:23:11 +02:00
parent f33eb7b444
commit 9dd3e6476f
11 changed files with 173 additions and 252 deletions

View File

@ -169,7 +169,7 @@ class account_cash_statement(osv.osv):
return result
_columns = {
'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Total Cash Transactions",
'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Total Transactions",
store = {
'account.bank.statement': (lambda self, cr, uid, ids, context=None: ids, ['line_ids','move_line_ids'], 10),
'account.bank.statement.line': (_get_statement_from_line, ['amount'], 10),

View File

@ -51,7 +51,6 @@ Main features:
'wizard/pos_confirm.xml',
'wizard/pos_discount.xml',
'wizard/pos_open_statement.xml',
'wizard/pos_close_statement.xml',
'wizard/pos_payment_report_user_view.xml',
'wizard/pos_sales_user.xml',
'wizard/pos_receipt_view.xml',

View File

@ -195,23 +195,17 @@ class pos_session(osv.osv):
required=True,
select=1,
domain="[('state', '=', 'active')]",
# readonly=True,
# states={'draft' : [('readonly', False)]}
),
'name' : fields.char('Session ID', size=32,
required=True,
# readonly=True,
# states={'draft' : [('readonly', False)]}
),
'name' : fields.char('Session ID', size=32, required=True, readonly=True),
'user_id' : fields.many2one('res.users', 'Responsible',
required=True,
select=1,
# readonly=True,
# states={'draft' : [('readonly', False)]}
readonly=True,
states={'opening_control' : [('readonly', False)]}
),
'start_at' : fields.datetime('Opening Date'),
'stop_at' : fields.datetime('Closing Date'),
'start_at' : fields.datetime('Opening Date', readonly=True),
'stop_at' : fields.datetime('Closing Date', readonly=True),
'state' : fields.selection(POS_SESSION_STATE, 'State',
required=True, readonly=True,
@ -281,7 +275,7 @@ class pos_session(osv.osv):
for session in self.browse(cr, uid, ids, context=None):
# open if there is no session in 'opening_control', 'opened', 'closing_control' for one user
domain = [
('state', '!=', 'closed'),
('state', 'not in', ('closed','closing_control')),
('user_id', '=', uid)
]
count = self.search_count(cr, uid, domain, context=context)
@ -344,7 +338,7 @@ class pos_session(osv.osv):
record.write(values, context=context)
for st in record.statement_ids:
st.button_open(context=context)
return True
return self.open_frontend_cb(cr, uid, ids, context=context)
def wkf_action_opening_control(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state' : 'opening_control'}, context=context)
@ -352,7 +346,7 @@ class pos_session(osv.osv):
def wkf_action_closing_control(self, cr, uid, ids, context=None):
for session in self.browse(cr, uid, ids, context=context):
for statement in session.statement_ids:
if not statement.journal_id.closing_control:
if statement.id <> session.cash_register_id.id:
if statement.balance_end<>statement.balance_end_real:
self.pool.get('account.bank.statement').write(cr, uid,
[statement.id], {'balance_end_real': statement.balance_end})
@ -377,7 +371,7 @@ class pos_session(osv.osv):
name= _('Point of Sale Loss')
if not account_id:
raise osv.except_osv( _('Error!'),
_("Please set your profit and loss accounts on your payment method '%s'.") % (st.journal_id.name,))
_("Please set your profit and loss accounts on your payment method '%s'. This will allow OpenERP to post the difference of %.2f in your ending balance. To close this session, you can update the 'Closing Cash Control' to avoid any difference.") % (st.journal_id.name,st.difference))
bsl.create(cr, uid, {
'statement_id': st.id,
'amount': st.difference,
@ -388,7 +382,15 @@ class pos_session(osv.osv):
getattr(st, 'button_confirm_%s' % st.journal_id.type)(context=context)
self._confirm_orders(cr, uid, ids, context=context)
return self.write(cr, uid, ids, {'state' : 'closed'}, context=context)
self.write(cr, uid, ids, {'state' : 'closed'}, context=context)
obj = self.pool.get('ir.model.data').get_object_reference(cr, uid, 'point_of_sale', 'menu_point_root')[1]
return {
'type' : 'ir.actions.client',
'name' : 'Point of Sale Menu',
'tag' : 'reload',
'params' : {'menu_id': obj},
}
def _confirm_orders(self, cr, uid, ids, context=None):
wf_service = netsvc.LocalService("workflow")
@ -413,10 +415,8 @@ class pos_session(osv.osv):
def open_frontend_cb(self, cr, uid, ids, context=None):
if not context:
context = {}
if not ids:
return {}
context.update({'session_id' : ids[0]})
return {
'type' : 'ir.actions.client',

View File

@ -15,7 +15,7 @@
</data>
<data>
<record model="pos.config" id="pos_config_main">
<field name="name">Main PoS</field>
<field name="name">Main</field>
</record>
</data>

View File

@ -3,9 +3,9 @@
<data>
<!-- Top menu item -->
<menuitem name="PoS Backend"
<menuitem name="Point of Sale"
id="menu_point_root"
groups="group_pos_manager"
groups="group_pos_manager,group_pos_user"
sequence="140"/>
<record id="categ_others" model="pos.category">
@ -156,7 +156,7 @@
</record>
<menuitem name="Daily Operations" id="menu_point_of_sale" parent="menu_point_root" sequence="10" />
<menuitem parent="menu_point_of_sale" id="menu_point_ofsale" action="action_pos_pos_form" sequence="1" groups="group_pos_manager,group_pos_user"/>
<menuitem parent="menu_point_of_sale" id="menu_point_ofsale" action="action_pos_pos_form" sequence="2" groups="group_pos_manager,group_pos_user"/>
<menuitem name="Products" id="menu_point_of_sale_product" parent="menu_point_root" sequence="15" />
<record id="product_normal_action" model="ir.actions.act_window">
@ -764,18 +764,6 @@
</record>
<!-- Top menu item -->
<!--
right now it's not possible to directly call a client action
from a menuitem, so we can't use this shortcut element and
use an explicit record element instead
-->
<record id="menu_point_root_touchscreen" model="ir.ui.menu">
<field name="name">Point of Sale</field>
<field name="action" ref="action_pos_pos"/>
<field name="groups_id" eval="[(6, 0, [ref('point_of_sale.group_pos_manager'), ref('point_of_sale.group_pos_user')])]"/>
<field name="sequence">150</field>
</record>
<record model="ir.ui.view" id="view_pos_config_form">
<field name="name">pos.config.form.view</field>
<field name="model">pos.config</field>
@ -896,81 +884,93 @@
<field name="arch" type="xml">
<form string="Point of Sale Session" version="7.0">
<header>
<button name="open" type="workflow" string="Validate &amp; Open Session" states="opening_control" />
<button name="cashbox_control" type="workflow" string="End of Session" states="opened" />
<button name="close" type="workflow" string="Validate &amp; Close" states="closing_control,opened" />
<button name="open" type="workflow" string="Validate &amp; Open Session" states="opening_control" class="oe_highlight"/>
<button name="cashbox_control" type="workflow" string="End of Session" states="opened"
class="oe_highlight"/>
<button name="close" type="workflow" string="Validate Closing &amp; Post Entries" states="closing_control"
class="oe_highlight"/>
<button name="open_frontend_cb" type="object" string="Start Selling" states="opened"/>
<div class="oe_right">
<field name="state" widget="statusbar" statusbar_visible="opening_control,opened,closing_control,closed" nolabel="1"/>
</div>
</header>
<sheet>
<group>
<field name="config_id"/>
<div class="oe_right oe_button_box">
<button name="%(action_pos_box_in)d" string="Put Money In" type="action" states="opened,closing_control"/>
<button name="%(action_pos_box_out)d" string="Take Money Out" type="action" states="opened,closing_control"/>
</div>
<h1 class="oe_title">
Point of Sale Session:
<field name="name" attrs="{'invisible': [('name','=','/')]}" class="oe_inline"/>
</h1>
<field name="config_id" invisible="1"/>
<field name="has_opening_control" invisible="1" />
<field name="has_closing_control" invisible="1" />
<group>
<button name="%(action_pos_box_in)d" string="Put Money In" type="action" states="opened"/>
<button name="%(action_pos_box_out)d" string="Take Money Out" type="action" states="opened"/>
<button name="open_frontend_cb" type="object" string="Open Point Of Sale" states="opened" />
</group>
<newline/>
<field name="user_id" />
<field name="name" />
<newline/>
<field name="start_at" attrs="{'insivible' : [('state', '=', 'opening_control')]}"/>
<field name="stop_at" attrs="{'insivible' : [('state', '=', 'opening_control')]}"/>
<separator string="Cash Control" colspan="4"/>
<field name="cash_register_id" invisible="1" />
<field name="opening_details_ids" colspan="4" nolabel="1" attrs="{'invisible' : [('state', 'not in', ('opening_control',))]}">
<tree string="Opening Cashbox Lines" editable="bottom">
<field name="pieces" readonly="1" />
<field name="number_opening" string="Opening Unit Numbers" on_change="on_change_sub_opening(pieces, number_opening, parent.balance_end)" />
<field name="subtotal_opening" string="Opening Subtotal" sum="Total"/>
</tree>
</field>
<group>
<group>
<field name="user_id"/>
</group>
<group>
<field name="start_at" attrs="{'invisible' : [('state', '=', 'opening_control')]}"/>
<field name="stop_at" attrs="{'invisible' : [('state', '&lt;&gt;', 'closed')]}"/>
</group>
<newline/>
<field name="details_ids" colspan="4" nolabel="1" attrs="{'invisible': [('state', '=', 'opening_control')]}">
<tree string="Cashbox Lines" editable="bottom">
<field name="pieces" readonly="1" />
<field name="number_opening" readonly="1"/>
<field name="subtotal_opening"/>
<field name="number_closing"/>
<field name="subtotal_closing"/>
</tree>
</field>
<group col="4" colspan="4">
<group col="2" colspan="2">
<separator string="Cash Balance" colspan="2"/>
<field name="cash_register_balance_start" readonly="1" string="Opening Cash Control"/>
<field name="cash_register_total_entry_encoding" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="+ Transactions"/>
<field name="cash_register_balance_end" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="= Theorical Cash Closing"/>
</group>
<group col="2" colspan="2" attrs="{'invisible' : [('state', '=', 'opening_control')]}">
<separator string="Cash Closing Balance" colspan="2"/>
<field name="cash_register_balance_end_real"/>
<field name="cash_register_difference" />
</group>
<group string="Opening Cash Control">
<field name="opening_details_ids" nolabel="1" colspan="2" attrs="{'readonly' : [('state', 'not in', ('opening_control',))]}">
<tree string="Opening Cashbox Lines" editable="bottom">
<field name="pieces" readonly="1" />
<field name="number_opening" string="Opening Unit Numbers" on_change="on_change_sub_opening(pieces, number_opening)" />
<field name="subtotal_opening" string="Opening Subtotal" sum="Total"/>
</tree>
</field>
</group>
<group string="Closing Cash Control" attrs="{'invisible': [('state', '=', 'opening_control')]}">
<field name="details_ids" nolabel="1" colspan="2">
<tree string="Cashbox Lines" editable="bottom">
<field name="pieces" readonly="1" />
<field name="number_closing"/>
<field name="subtotal_closing"/>
</tree>
</field>
</group>
<separator string="Summary by Payment Methods" colspan="4" attrs="{'invisible' : [('state', '=', 'opening_control')]}"/>
<field name="statement_ids" colspan="4" nolabel="1" attrs="{'invisible' : [('state', '=', 'opening_control')]}">
<tree string="Statements">
<field name="name" />
<field name="journal_id" />
<field name="balance_start" />
<field name="total_entry_encoding" />
<field name="balance_end_real" />
<field name="difference" />
<field name="currency" />
<field name="state" />
</tree>
</field>
<div>
<group class="oe_subtotal_footer oe_right">
<field name="cash_register_balance_start" readonly="1" string="Opening Balance" class="oe_subtotal_footer_separator"/>
<field name="cash_register_total_entry_encoding" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="+ Transactions"/>
<field name="cash_register_balance_end" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="= Theorical Balance"/>
</group>
<div attrs="{'invisible' : [('state', '&lt;&gt;', 'opening_control')]}" class="oe_view_nocontent" groups="point_of_sale.group_pos_manager">
<p class="oe_view_nocontent_create">
You can define another list of available currencies on the
<i>Cash Registers</i> tab of the <b><field name="cash_register_id" class="oe_inline"/></b>
payment method.
</p>
</div>
</div>
<group class="oe_subtotal_footer oe_right" attrs="{'invisible' : [('state', '=', 'opening_control')]}">
<field name="cash_register_balance_end_real" class="oe_subtotal_footer_separator"/>
<field name="cash_register_difference" class="oe_subtotal_footer_separator"/>
</group>
</group>
<separator string="Summary by Payment Methods" attrs="{'invisible' : [('state', '=', 'opening_control')]}"/>
<field name="statement_ids" attrs="{'invisible' : [('state', '=', 'opening_control')]}">
<tree string="Statements">
<field name="name" />
<field name="journal_id" />
<field name="balance_start" />
<field name="total_entry_encoding" />
<field name="balance_end_real" />
<field name="difference" />
<field name="currency" />
<field name="state" />
</tree>
</field>
</sheet>
</form>
</field>
@ -987,6 +987,7 @@
<field name="user_id" />
<field name="start_at" />
<field name="stop_at" />
<field name="state" />
</tree>
</field>
</record>
@ -1021,18 +1022,11 @@
<field name="search_view_id" ref="view_pos_session_search" />
</record>
<menuitem
parent="menu_point_rep"
action="action_pos_session"
id="menu_pos_session"
sequence="0"
groups="group_pos_manager"/>
<menuitem
parent="menu_point_of_sale"
action="action_pos_session"
id="menu_pos_session_all"
sequence="0"
sequence="1"
groups="group_pos_manager"/>
<record id="view_pos_order_filter" model="ir.ui.view">
@ -1060,7 +1054,9 @@
</field>
</record>
<menuitem action="action_pos_session_opening" parent="menu_point_of_sale" id="menu_pos_session_opening" sequence="0" />
<menuitem action="action_pos_session_opening"
parent="menu_point_of_sale"
id="menu_pos_session_opening" sequence="0"/>
</data>
</openerp>

View File

@ -875,7 +875,7 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
},
close: function() {
this.pos.barcode_reader.disconnect();
return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_pos_close_statement']], ['res_id']).pipe(
return new instance.web.Model("ir.model.data").get_func("search_read")([['name', '=', 'action_client_pos_menu']], ['res_id']).pipe(
_.bind(function(res) {
return this.rpc('/web/action/load', {'action_id': res[0]['res_id']}).pipe(_.bind(function(result) {
var action = result.result;

View File

@ -22,7 +22,6 @@
import pos_confirm
import pos_discount
import pos_open_statement
import pos_close_statement
import pos_details
import pos_sales_user
import pos_sales_user_today

View File

@ -1,76 +0,0 @@
# -*- coding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
##############################################################################
from osv import osv
from tools.translate import _
class pos_close_statement(osv.osv_memory):
_name = 'pos.close.statement'
_description = 'Close Statements'
def cancel_wizard(self, cr, uid, ids, context=None):
if context.get('cancel_action'):
return context['cancel_action']
def close_statement(self, cr, uid, ids, context=None):
"""
Close the statements
@param self: The object pointer.
@param cr: A database cursor
@param uid: ID of the user currently logged in
@param context: A standard dictionary
@return : Blank Dictionary
"""
context = context or {}
mod_obj = self.pool.get('ir.model.data')
statement_obj = self.pool.get('account.bank.statement')
journal_obj = self.pool.get('account.journal')
j_ids = journal_obj.search(cr, uid, [('journal_user','=',1)], context=context)
ids = statement_obj.search(cr, uid, [('state', '!=', 'confirm'), ('user_id', '=', uid), ('journal_id', 'in', j_ids)], context=context)
if not ids:
raise osv.except_osv(_('Message'), _('Cash registers are already closed.'))
for statement in statement_obj.browse(cr, uid, ids, context=context):
statement_obj.write(cr, uid, [statement.id], {
'balance_end_real': statement.balance_end
}, context=context)
if not statement.journal_id.check_dtls:
statement_obj.button_confirm_cash(cr, uid, [statement.id], context=context)
tree_res = mod_obj.get_object_reference(cr, uid, 'point_of_sale', 'view_cash_statement_pos_tree')
tree_id = tree_res and tree_res[1] or False
form_res = mod_obj.get_object_reference(cr, uid, 'account', 'view_bank_statement_form2')
form_id = form_res and form_res[1] or False
search_res = mod_obj.get_object_reference(cr, uid, 'account', 'view_account_bank_statement_filter')
return {
'domain': str([('id', 'in', ids)]),
'name': _('Close Cash Registers'),
'view_type': 'form',
'view_mode': 'tree,form',
'search_view_id': search_res and search_res[1] or False,
'res_model': 'account.bank.statement',
'views': [(tree_id, 'tree'), (form_id, 'form')],
'type': 'ir.actions.act_window'
}
pos_close_statement()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -1,45 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<openerp>
<data>
<!-- Point of Sale Confirm -->
<record id="view_pos_close_statement" model="ir.ui.view">
<field name="name">Close Statements</field>
<field name="model">pos.close.statement</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Close Cash Registers" version="7.0">
<header>
<button name="close_statement" string="Yes"
type="object" class="oe_highlight" />
<button type="object" name="cancel_wizard"
string="No" invisible="not context.get('cancel_action')" class="oe_highlight" />
or
<button string="Cancel" class="oe_link" special="cancel" />
</header>
<separator string="Do you want to close your cash registers?"/>
<label string="OpenERP will close all cash registers he can close automatically without validation. He will also open all cash registers for which you have to control the ending balance before closing manually."/>
</form>
</field>
</record>
<!--
<act_window name="Close Statements"
res_model="pos.close.statement"
src_model="account.bank.statement"
view_mode="form"
target="new"
key2="client_action_multi"
id="act_pos_open_statement"/>
-->
<record id="action_pos_close_statement" model="ir.actions.act_window">
<field name="name">Close Cash Register</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">pos.close.statement</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
</record>
</data>
</openerp>

View File

@ -10,8 +10,26 @@ class pos_session_opening(osv.osv_memory):
_columns = {
'pos_config_id' : fields.many2one('pos.config', 'Point of Sale', required=True),
'pos_session_id' : fields.many2one('pos.session', 'PoS Session'),
'pos_state' : fields.char('Session State'),
}
def open_ui(self, cr, uid, ids, context=None):
context = context or {}
data = self.browse(cr, uid, ids[0], context=context)
context['active_id'] = data.pos_session_id.id
return {
'type' : 'ir.actions.client',
'name' : 'Start Point Of Sale',
'tag' : 'pos.ui',
'context' : context
}
def open_existing_session_cb_close(self, cr, uid, ids, context=None):
wf_service = netsvc.LocalService("workflow")
wizard = self.browse(cr, uid, ids[0], context=context)
wf_service.trg_validate(uid, 'pos.session', wizard.pos_session_id.id, 'cashbox_control', cr)
return self.open_session_cb(cr, uid, ids, context)
def open_session_cb(self, cr, uid, ids, context=None):
assert len(ids) == 1, "you can open only one session at a time"
proxy = self.pool.get('pos.session')
@ -42,18 +60,21 @@ class pos_session_opening(osv.osv_memory):
}
def on_change_config(self, cr, uid, ids, config_id, context=None):
result = {
'pos_session_id': False,
'pos_state': False
}
if not config_id:
return {}
return {'value': result}
proxy = self.pool.get('pos.session')
session_ids = proxy.search(cr, uid, [
('state', '<>', 'closed'),
('config_id', '=', config_id),
], context=context)
return {
'value' : {
'pos_session_id' : session_ids and session_ids[0] or False,
}
}
if session_ids:
result['pos_state'] = proxy.browse(cr, uid, session_ids[0], context=context).state
result['pos_session_id'] = session_ids[0]
return {'value' : result}
def default_get(self, cr, uid, fieldnames, context=None):
so = self.pool.get('pos.session')
@ -63,9 +84,10 @@ class pos_session_opening(osv.osv_memory):
else:
current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
result = current_user.pos_config and current_user.pos_config.id or False
if not result:
r = self.pool.get('pos.config').search(cr, uid, [], context=context)
result = r and r[0] or False
return {
'pos_config_id' : result,
'pos_session_id': session_ids and session_ids[0] or False
'pos_config_id' : result
}
pos_session_opening()

View File

@ -7,28 +7,54 @@
<field name="arch" type="xml">
<form string="PoS Session Opening" version="7.0">
<separator string="Select your Point of Sale" colspan="4" />
<field name="pos_config_id" on_change="on_change_config(pos_config_id)" widget="selection" domain="[('state','=','active')]"/>
<field name="pos_session_id" invisible="1"/>
<group colspan="4">
<button special="cancel" icon="gtk-cancel" string="Cancel" />
<button name="open_existing_session_cb" type="object" string="Open Session" icon="gtk-ok"
attrs="{'invisible' : [('pos_session_id', '=', False)]}"
/>
<button name="open_session_cb" type="object" string="New Session" icon="gtk-ok"
attrs="{'invisible' : [('pos_session_id', '!=', False)]}"
/>
<group>
<field name="pos_config_id" on_change="on_change_config(pos_config_id)"
widget="selection" domain="[('state','=','active')]"
class="oe_inline"/>
</group>
<field name="pos_session_id" invisible="1"/>
<field name="pos_state" invisible="1"/>
<button name="open_ui" type="object" string="Start Selling"
attrs="{'invisible' : [('pos_state', 'not in', ('opened',))]}"
class="oe_highlight"
/>
<button name="open_existing_session_cb" type="object" string="Open Session"
attrs="{'invisible' : [('pos_state', 'not in', ('opening_control',))]}"
class="oe_highlight"
/>
<button name="open_existing_session_cb_close" type="object" string="Close Session"
attrs="{'invisible' : [('pos_state', 'not in', ('opened',))]}"
/>
<button name="open_existing_session_cb" type="object" string="Close Session"
attrs="{'invisible' : [('pos_state', 'not in', ('closing_control',))]}"
class="oe_highlight"
/>
<button name="open_session_cb" type="object" string="New Session"
attrs="{'invisible' : ['|', ('pos_state', '!=', False),('pos_config_id','=',False)]}"
class="oe_highlight"
/>
<div attrs="{'invisible' : ['|', ('pos_state', '!=', False),('pos_config_id','=',False)]}" class="oe_view_nocontent">
<p class="oe_view_nocontent_create">
Click to start a session.
</p><p>
You will first have to control your cash amount in your cash register.
Then you will be able to open the session and start selling with the touchscreen
interface.
</p>
</div>
</form>
</field>
</record>
<record id="action_pos_session_opening" model="ir.actions.act_window">
<field name="name">Open/Close a Session</field>
<field name="name">Your Session</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">pos.session.opening</field>
<field name="view_type">form</field>
<field name="view_mode">form</field>
<field name="target">new</field>
<field name="target">inline</field>
</record>
</data>
</openerp>