[IMP] PoS Backend

Improved layout of "PoS orders", "PoS Sessions" and "PoS Config" for useability
	Apply new design layouts for web client v7.0
	Rename PoS by Point of Sale everywhere
	Some typos, improved views
	Reviewed menu structure
"Default Point of Sale" field accessible through users preferences
PoS Config:
	Sequence is readonly
	Removed the "Draft" state --> easier, you do not need to active a PoS Config
	Default values on Shop and Journals
PoS Orders:
	Changed shop_id & journal_id on PoS Orders --> from normal fields to related field, depending on the session
Open Session:
	Fixed the wizard
	Several bugfixes and useability improvements
	Accounting Transactions posted at the close (not at the control)
Cash Registers:
	Lots of cleanups and bugfixes
Pos Sessions:
	Fixes and improved layout
	Better computation of all fields
	removed unused object "pos.config.journal"
PoS Orders:
	Default session_id

bzr revid: fp@openerp.com-20120512223743-b1vvbbybo8xq7e54
This commit is contained in:
Fabien Pinckaers 2012-05-13 00:37:43 +02:00
parent 589b298125
commit 341c6b0843
18 changed files with 364 additions and 733 deletions

View File

@ -53,36 +53,11 @@ class account_bank_statement(osv.osv):
return False
def _end_balance(self, cursor, user, ids, name, attr, context=None):
res_currency_obj = self.pool.get('res.currency')
res_users_obj = self.pool.get('res.users')
res = {}
company_currency_id = res_users_obj.browse(cursor, user, user,
context=context).company_id.currency_id.id
statements = self.browse(cursor, user, ids, context=context)
for statement in statements:
for statement in self.browse(cursor, user, ids, context=context):
res[statement.id] = statement.balance_start
currency_id = statement.currency.id
for line in statement.move_line_ids:
if line.debit > 0:
if line.account_id.id == \
statement.journal_id.default_debit_account_id.id:
res[statement.id] += res_currency_obj.compute(cursor,
user, company_currency_id, currency_id,
line.debit, context=context)
else:
if line.account_id.id == \
statement.journal_id.default_credit_account_id.id:
res[statement.id] -= res_currency_obj.compute(cursor,
user, company_currency_id, currency_id,
line.credit, context=context)
if statement.state in ('draft', 'open'):
for line in statement.line_ids:
res[statement.id] += line.amount
for r in res:
res[r] = round(res[r], 2)
for line in statement.line_ids:
res[statement.id] += line.amount
return res
def _get_period(self, cr, uid, context=None):
@ -122,7 +97,7 @@ class account_bank_statement(osv.osv):
_description = "Bank Statement"
_columns = {
'name': fields.char('Name', size=64, required=True, states={'draft': [('readonly', False)]}, readonly=True, help='if you give the Name other then /, its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself'), # readonly for account_cash_statement
'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}, select=True),
'date': fields.date('Creation Date', required=True, states={'confirm': [('readonly', True)]}, select=True),
'journal_id': fields.many2one('account.journal', 'Journal', required=True,
readonly=True, states={'draft':[('readonly',False)]}),
'period_id': fields.many2one('account.period', 'Period', required=True,
@ -133,7 +108,7 @@ class account_bank_statement(osv.osv):
states={'confirm': [('readonly', True)]}),
'balance_end': fields.function(_end_balance,
store = {
'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10),
'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids','balance_start'], 10),
'account.bank.statement.line': (_get_statement, ['amount'], 10),
},
string="Computed Balance", help='Balance as calculated based on Starting Balance and transaction lines'),
@ -303,7 +278,7 @@ class account_bank_statement(osv.osv):
def balance_check(self, cr, uid, st_id, journal_type='bank', context=None):
st = self.browse(cr, uid, st_id, context=context)
if not ((abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001) or (abs((st.balance_end or 0.0) - st.balance_end_cash) < 0.0001)):
if not ((abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001) or (abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001)):
raise osv.except_osv(_('Error !'),
_('The statement balance is incorrect !\nThe expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end))
return True

View File

@ -61,8 +61,8 @@ class account_cashbox_line(osv.osv):
'pieces': fields.float('Unit of Currency', digits_compute=dp.get_precision('Account')),
'number_opening' : fields.integer('Number of Units', help='Opening Unit Numbers'),
'number_closing' : fields.integer('Number of Units', help='Closing Unit Numbers'),
'subtotal_opening': fields.function(_sub_total, string='Subtotal Opening', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
'subtotal_closing': fields.function(_sub_total, string='Subtotal Closing', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
'subtotal_opening': fields.function(_sub_total, string='Opening Subtotal', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
'subtotal_closing': fields.function(_sub_total, string='Closing Subtotal', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
'bank_statement_id' : fields.many2one('account.bank.statement', ondelete='cascade'),
}
@ -72,36 +72,26 @@ class account_cash_statement(osv.osv):
_inherit = 'account.bank.statement'
def _get_starting_balance(self, cr, uid, ids, context=None):
""" Find starting balance
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
def _update_balances(self, cr, uid, ids, context=None):
"""
Set starting and ending balances according to pieces count
"""
res = {}
print 'Updating'
for statement in self.browse(cr, uid, ids, context=context):
if statement.journal_id.type not in('cash'):
if statement.journal_id.type not in ('cash',):
continue
res[statement.id] = {
'balance_start': sum((line.pieces * line.number_opening
for line in statement.details_ids), 0.0)
start = end = 0
for line in statement.details_ids:
start += line.subtotal_opening
end += line.subtotal_closing
data = {
'balance_start': start,
'balance_end_real': end,
}
print "_get_starting_balance: %r" % (res,)
return res
def _balance_end_cash(self, cr, uid, ids, name, arg, context=None):
""" Find ending balance "
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
"""
res = {}
for statement in self.browse(cr, uid, ids, context=context):
res[statement.id] = sum((line.pieces * line.number_closing
for line in statement.details_ids), 0.0)
print "_balance_end_cash: %r" % (res,)
res[statement.id] = data
print statement.id, data
super(account_cash_statement, self).write(cr, uid, [statement.id], data, context=context)
return res
def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None):
@ -114,7 +104,6 @@ class account_cash_statement(osv.osv):
res = {}
for statement in self.browse(cr, uid, ids, context=context):
res[statement.id] = sum((line.amount for line in statement.line_ids), 0.0)
print "_get_sum_entry_encoding: %r" % (res,)
return res
def _get_company(self, cr, uid, context=None):
@ -126,63 +115,7 @@ class account_cash_statement(osv.osv):
company_id = company_pool.search(cr, uid, [])
return company_id and company_id[0] or False
def _get_cash_open_box_lines(self, cr, uid, context=None):
res = []
curr = [1, 2, 5, 10, 20, 50, 100, 500]
for rs in curr:
dct = {
'pieces': rs,
'number': 0
}
res.append(dct)
journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash')], context=context)
if journal_ids:
results = self.search(cr, uid, [('journal_id', 'in', journal_ids),('state', '=', 'confirm')], context=context)
if results:
cash_st = self.browse(cr, uid, results, context=context)[0]
for cash_line in cash_st.ending_details_ids:
for r in res:
if cash_line.pieces == r['pieces']:
r['number'] = cash_line.number
return res
def _get_default_cash_close_box_lines(self, cr, uid, context=None):
res = []
curr = [1, 2, 5, 10, 20, 50, 100, 500]
for rs in curr:
dct = {
'pieces': rs,
'number': 0
}
res.append(dct)
return res
def _get_cash_close_box_lines(self, cr, uid, context=None):
res = []
curr = [1, 2, 5, 10, 20, 50, 100, 500]
for rs in curr:
dct = {
'pieces': rs,
'number': 0
}
res.append((0, 0, dct))
return res
def _get_cash_open_close_box_lines(self, cr, uid, context=None):
res = {}
start_l = []
end_l = []
starting_details = self._get_cash_open_box_lines(cr, uid, context=context)
ending_details = self._get_default_cash_close_box_lines(cr, uid, context)
for start in starting_details:
start_l.append((0, 0, start))
for end in ending_details:
end_l.append((0, 0, end))
res['start'] = start_l
res['end'] = end_l
return res
def _get_statement(self, cr, uid, ids, context=None):
def _get_statement_from_line(self, cr, uid, ids, context=None):
result = {}
for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
result[line.statement_id.id] = True
@ -192,83 +125,46 @@ class account_cash_statement(osv.osv):
result = dict.fromkeys(ids, 0.0)
for obj in self.browse(cr, uid, ids, context=context):
result[obj.id] = obj.balance_end - obj.balance_end_cash
result[obj.id] = obj.balance_end_real - obj.balance_end
return result
_columns = {
'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Cash Transaction", help="Total cash transactions",
'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Total Cash 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, ['amount'], 10),
'account.bank.statement.line': (_get_statement_from_line, ['amount'], 10),
}),
'closing_date': fields.datetime("Closed On"),
'balance_end_cash': fields.function(_balance_end_cash, store=False, string='Closing Balance', help="Closing balance based on cashBox"),
'details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='CashBox Lines'),
'opening_details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='Opening Cashbox Lines'),
'closing_details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='Closing Cashbox Lines'),
'user_id': fields.many2one('res.users', 'Responsible', required=False),
'difference' : fields.function(_compute_difference, method=True, string="Difference", type="float"),
}
_defaults = {
'state': 'draft',
'date': lambda self, cr, uid, context={}: context.get('date', time.strftime("%Y-%m-%d %H:%M:%S")),
'user_id': lambda self, cr, uid, context=None: uid,
}
def check_opening_journal(self, cr, uid, ids, context=None):
"""
This constraint will check than the journal is not used twice in the system,
to avoid a concurrency opening of this journal.
"""
for cash in self.browse(cr, uid, ids, context=None):
domain = [
('id', '!=', cash.id),
('journal_id', '=', cash.journal_id.id),
('journal_id.type', '=', 'cash'),
('state', 'in', ('open',)),
]
count = self.search_count(cr, uid, domain, context=context)
if count:
return False
return True
_constraints = [
#(check_opening_journal, "The selected journal has been opened !", ['journal_id']),
]
def create(self, cr, uid, vals, context=None):
if self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context).type == 'cash':
amount_total = 0.0
for line in vals.get('details_ids',[]):
print "line: %r" % (line,)
if line and len(line)==3 and line[2]:
# FIXME: If there is no piece # does not work with GTK
amount_total+= line[2].get('pieces', 0) * line[2]['number_opening']
journal = False
if vals.get('journal_id'):
journal = self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context)
if journal and (journal.type == 'cash') and not vals.get('details_ids'):
vals['details_ids'] = []
for value in journal.cashbox_line_ids:
nested_values = {
'number_closing' : 0,
'number_opening' : 0,
'pieces' : value.pieces
}
vals['details_ids'].append([0, False, nested_values])
vals.update(balance_start= amount_total)
vals.update(balance_end_real=self._compute_balance_end_real(cr, uid, vals['journal_id'], context=context))
details = vals.get('details_ids')
if not details:
result = self.onchange_journal_id(cr, uid, None, vals['journal_id'], context=context)
vals['details_ids'] = []
for value in (result['value']['details_ids'] or []):
print "value: %r" % (value,)
nested_values = {
'number_closing' : False,
'number_opening' : False,
'pieces' : value['pieces'],
'subtotal_closing' : False,
'subtotal_opening' : False,
}
vals['details_ids'].append([0, False, nested_values])
return super(account_cash_statement, self).create(cr, uid, vals, context=context)
res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context)
self._update_balances(cr, uid, [res_id], context)
return res_id
def write(self, cr, uid, ids, vals, context=None):
"""
@ -284,54 +180,9 @@ class account_cash_statement(osv.osv):
@return: True on success, False otherwise
"""
super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
res = self._get_starting_balance(cr, uid, ids)
for rs in res:
super(account_cash_statement, self).write(cr, uid, [rs], res.get(rs))
return True
def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
""" Changes balance start and starting details if journal_id changes"
@param statement_id: Changed statement_id
@param journal_id: Changed journal_id
@return: Dictionary of changed values
"""
balance_start = 0.0
if journal_id:
count = self.search_count(cr, uid, [('journal_id', '=', journal_id),('state', '=', 'open')], context=None)
if 0: # count:
journal = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context)
raise osv.except_osv(_('Error !'), (_('The Account Journal %s is opened by an other Cash Register !') % (journal.name,)))
else:
values = super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context)
proxy_line = self.pool.get('account.cashbox.line')
values.setdefault('value', {})
values['value']['details_ids'] = []
values['value']['balance_end_real'] = self._compute_balance_end_real(cr, uid, journal_id, context=context)
values['value']['balance_start'] = 0.0
journal = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context)
for line in journal.cashbox_line_ids:
values['value']['details_ids'].append({'pieces' : line.pieces})
return values
else:
return {
'value' : {
'balance_start': balance_start,
'details_ids' : [],
}
}
return super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context)
def _equal_balance(self, cr, uid, cash_id, context=None):
statement = self.browse(cr, uid, cash_id, context=context)
self.write(cr, uid, [cash_id], {'balance_end_real': statement.balance_end})
if statement.balance_end != statement.balance_end_cash:
return False
return True
res = super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
self._update_balances(cr, uid, ids, context)
return res
def _user_allow(self, cr, uid, statement_id, context=None):
return True
@ -347,7 +198,7 @@ class account_cash_statement(osv.osv):
for statement in statement_pool.browse(cr, uid, ids, context=context):
vals = {}
if not self._user_allow(cr, uid, statement.id, context=context):
raise osv.except_osv(_('Error !'), (_('User %s does not have rights to access %s journal !') % (statement.user_id.name, statement.journal_id.name)))
raise osv.except_osv(_('Error !'), (_('You do not have rights to open this %s journal !') % (statement.journal_id.name, )))
if statement.name and statement.name == '/':
c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id}
@ -365,13 +216,6 @@ class account_cash_statement(osv.osv):
self.write(cr, uid, [statement.id], vals, context=context)
return True
def balance_check(self, cr, uid, cash_id, journal_type='bank', context=None):
if journal_type == 'bank':
return super(account_cash_statement, self).balance_check(cr, uid, cash_id, journal_type, context)
if not self._equal_balance(cr, uid, cash_id, context):
raise osv.except_osv(_('Error !'), _('The closing balance should be the same than the computed balance!'))
return True
def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
if journal_type == 'bank':
return super(account_cash_statement, self).statement_close(cr, uid, ids, journal_type, context)
@ -417,14 +261,6 @@ class account_cash_statement(osv.osv):
return self.write(cr, uid, ids, {'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")}, context=context)
def button_cancel(self, cr, uid, ids, context=None):
cash_box_line_pool = self.pool.get('account.cashbox.line')
super(account_cash_statement, self).button_cancel(cr, uid, ids, context=context)
for st in self.browse(cr, uid, ids, context):
for end in st.details_ids:
cash_box_line_pool.write(cr, uid, [end.id], {'number_closing': 0})
return True
account_cash_statement()
class account_journal(osv.osv):

View File

@ -32,7 +32,7 @@
</field>
<separator colspan="4" string="States"/>
<group>
<field name="state" select="1" readonly="1"/>
<field name="state" readonly="1"/>
<button name="create_period" states="draft" string="Create Monthly Periods" type="object" icon="terp-document-new"/>
<button name="create_period3" states="draft" string="Create 3 Months Periods" type="object" icon="terp-document-new"/>
</group>
@ -162,13 +162,13 @@
<field name="arch" type="xml">
<form string="Account">
<group col="6" colspan="4">
<field name="name" select="1"/>
<field name="code" select="1"/>
<field name="name"/>
<field name="code" />
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
<newline/>
<field name="parent_id"/>
<field name="type" select="1"/>
<field name="user_type" select="1"/>
<field name="type"/>
<field name="user_type"/>
<field name="active"/>
<newline/>
<field name="debit" invisible="context.get('config_invisible', True)" attrs="{'readonly':[('type','=','view')]}"/>
@ -345,8 +345,8 @@
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Journal Column">
<field colspan="4" name="name" select="1"/>
<field name="field" select="1"/>
<field colspan="4" name="name"/>
<field name="field"/>
<field name="sequence"/>
</form>
</field>
@ -455,8 +455,8 @@
<field name="arch" type="xml">
<form string="Account Journal">
<group colspan="4" col="6">
<field name="name" select="1"/>
<field name="code" select="1"/>
<field name="name"/>
<field name="code"/>
<field name="type" on_change="onchange_type(type, currency, context)"/>
</group>
<notebook colspan="4">
@ -505,20 +505,19 @@
<separator colspan="4" string="Accounts Allowed (empty for no control)"/>
<field colspan="4" name="account_control_ids" nolabel="1"/>
</page>
<page string="Cash Box">
<page string="Cash">
<separator string="Profit &amp; Loss Accounts" colspan="4" />
<field name="profit_account_id" />
<field name="loss_account_id" />
<separator string="Internal Account" colspan="4" />
<field name="internal_account_id" />
<separator string="Cash Box Lines" colspan="4" />
<separator string="Available Currencies" colspan="4" />
<field name="cashbox_line_ids" nolabel="1" string="Unit Of Currency Definition" colspan="4">
<tree string="CashBox Lines" editable="bottom">
<field name="pieces" />
</tree>
</field>
<label string="The Cashbox Lines will be used in the PoS Session" />
</page>
</notebook>
</form>
@ -610,9 +609,9 @@
<field name="arch" type="xml">
<form string="Bank Statement">
<group col="7" colspan="4">
<field name="name" select="1"/>
<field name="date" select="1" on_change="onchange_date(date, company_id)"/>
<field name="journal_id" domain="[('type', '=', 'bank')]" on_change="onchange_journal_id(journal_id)" select="1" widget="selection"/>
<field name="name"/>
<field name="date" on_change="onchange_date(date, company_id)"/>
<field name="journal_id" domain="[('type', '=', 'bank')]" on_change="onchange_journal_id(journal_id)" widget="selection"/>
<newline/>
<field name="period_id"/>
<field name="balance_start"/>
@ -671,8 +670,8 @@
<field name="arch" type="xml">
<form string="Bank Statement">
<group col="7" colspan="4">
<field name="name" select="1"/>
<field name="date" select="1" on_change="onchange_date(date, company_id)"/>
<field name="name"/>
<field name="date" on_change="onchange_date(date, company_id)"/>
<field name='company_id' widget="selection" groups="base.group_multi_company" />
<field name="journal_id" domain="[('type', '=', 'bank')]" on_change="onchange_journal_id(journal_id)" widget="selection"/>
<newline/>
@ -802,12 +801,12 @@
<field name="arch" type="xml">
<form string="Account Type">
<group col="6" colspan="4">
<field name="name" select="1"/>
<field name="code" select="1"/>
<field name="name"/>
<field name="code"/>
</group>
<group col="2" colspan="2">
<separator string="Reporting Configuration" colspan="4"/>
<field name="report_type" select="2"/>
<field name="report_type"/>
</group>
<group col="2" colspan="2">
<separator string="Closing Method" colspan="4"/>
@ -859,9 +858,9 @@
<field name="arch" type="xml">
<form string="Journal Entry Reconcile">
<group col="6" colspan="4">
<field name="name" select="1"/>
<field name="create_date" select="1"/>
<field name="type" select="1"/>
<field name="name"/>
<field name="create_date"/>
<field name="type"/>
</group>
<separator colspan="4" string="Reconcile Entries"/>
<field colspan="4" name="line_id" nolabel="1"/>
@ -1097,9 +1096,9 @@
<field name="arch" type="xml">
<form string="Journal Item">
<group col="6" colspan="4">
<field name="name" select="1"/>
<field name="name"/>
<field name="ref"/>
<field name="partner_id" select="1" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
<field name="partner_id" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
<field name="journal_id"/>
<field name="period_id"/>
@ -1109,7 +1108,7 @@
<page string="Information">
<group col="2" colspan="2">
<separator colspan="2" string="Amount"/>
<field name="account_id" select="1" domain="[('company_id', '=', company_id), ('type','&lt;&gt;','view'), ('type','&lt;&gt;','consolidation')]"/>
<field name="account_id" domain="[('company_id', '=', company_id), ('type','&lt;&gt;','view'), ('type','&lt;&gt;','consolidation')]"/>
<field name="debit"/>
<field name="credit"/>
<field name="quantity"/>
@ -1124,7 +1123,7 @@
<group col="2" colspan="2">
<separator colspan="2" string="Dates"/>
<field name="date" select="1"/>
<field name="date"/>
<field name="date_maturity"/>
<field name="date_created" readonly="True"/>
</group>
@ -1179,11 +1178,11 @@
<notebook colspan="4">
<page string="Information">
<separator colspan="4" string="General Information"/>
<field name="name" select="1"/>
<field name="name"/>
<field name="date"/>
<field name="journal_id" readonly="False" select="1"/>
<field name="journal_id" readonly="False"/>
<field name="period_id" readonly="False"/>
<field name="account_id" select="1" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation'),('company_id', '=', company_id)]"/>
<field name="account_id" domain="[('type','&lt;&gt;','view'),('type','&lt;&gt;','consolidation'),('company_id', '=', company_id)]"/>
<field name="partner_id" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
<newline/>
<field name="debit"/>
@ -1192,13 +1191,13 @@
<separator colspan="4" string="Optional Information"/>
<field name="currency_id"/>
<field name="amount_currency"/>
<field name="quantity" select="3"/>
<field name="quantity"/>
<field name="move_id" required="False"/>
<newline/>
<field name="date_maturity"/>
<field name="date_created"/>
<field name="date_created"/>
<field name="blocked" select="3"/>
<field name="blocked"/>
<newline/>
<field name="account_tax_id" domain="[('parent_id','=',False)]"/>
<field name="analytic_account_id" domain="[('parent_id','!=',False)]" groups="analytic.group_analytic_accounting"/>
@ -2627,9 +2626,18 @@ action = pool.get('res.config').next(cr, uid, [], context)
<field name="model">account.bank.statement</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="Statement">
<form string="Statement" layout="manual">
<div class="oe_form_topbar">
<button name="button_cancel" states="confirm,open" string="Cancel" icon="terp-gtk-stop" type="object"/>
<button name="button_confirm_cash" states="open" string="Close CashBox" icon="terp-dialog-close" type="object"/>
<button name="button_open" states="draft" string="Open CashBox" icon="gtk-go-forward" type="object"/>
<div class="oe_right">
<field name="state" widget="statusbar" statusbar_visible="draft,open,confirm" nolabel="1"/>
</div>
</div>
<sheet layout="auto">
<group col="6" colspan="4">
<field name="name" select="1"/>
<field name="name"/>
<field name='company_id' widget="selection" groups="base.group_multi_company" />
<field name="journal_id" on_change="onchange_journal_id(journal_id)" select="1" widget="selection" domain="[('type', '=', 'cash')]"/>
<field name="user_id" select="1" readonly="1"/>
@ -2666,31 +2674,22 @@ action = pool.get('res.config').next(cr, uid, [], context)
</form>
</field>
</page>
<page string="CashBox">
<page string="Cash Control">
<group col="2" expand="1">
<field name="opening_details_ids" nolabel="1" colspan="4" attrs="{'invisible' : [('state', '!=', 'draft')]}">
<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)" attrs="{'readonly' : [('parent.state', '!=', 'open')]}" />
<field name="pieces"/>
<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"/>
</tree>
</field>
<field name="closing_details_ids" nolabel="1" colspan="4" attrs="{'invisible' : [('state', '!=', 'open')]}">
<field name="closing_details_ids" nolabel="1" colspan="4" attrs="{'invisible' : [('state', '=', 'draft')]}">
<tree string="Closing Cashbox Lines" editable="bottom">
<field name="pieces" readonly="1" />
<field name="number_opening" string="Opening Unit Numbers" readonly="1" />
<field name="subtotal_opening" string="Opening Subtotal" readonly="1" />
<field name="number_closing" string="Closing Unit Numbers" on_change="on_change_sub_closing(pieces, number_closing, parent.balance_end)" attrs="{'readonly' : [('parent.state', '!=', 'confirm')]}"/>
<field name="subtotal_closing" string="Closing Subtotal"/>
</tree>
</field>
<field name="details_ids" nolabel="1" readonly="True" attrs="{'invisible' : [('state', '!=', 'confirm')]}">
<tree string="Cashbox Lines">
<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)" attrs="{'readonly' : [('parent.state', '!=', 'open')]}" />
<field name="subtotal_opening" string="Opening Subtotal"/>
<field name="number_closing" string="Closing Unit Numbers" on_change="on_change_sub_closing(pieces, number_closing, parent.balance_end)" attrs="{'readonly' : [('parent.state', '!=', 'confirm')]}"/>
<field name="number_closing" string="Closing Unit Numbers" on_change="on_change_sub_closing(pieces, number_closing, parent.balance_end)"/>
<field name="subtotal_closing" string="Closing Subtotal"/>
</tree>
</field>
@ -2701,30 +2700,23 @@ action = pool.get('res.config').next(cr, uid, [], context)
</page>
</notebook>
<group col="6" colspan="4">
<group col="2" colspan="2">
<separator string="Dates" colspan="4"/>
<field name="date" select="1" attrs="{'readonly':[('state','!=','draft')]}" on_change="onchange_date(date, company_id)" string="Started On" />
<field name="closing_date" select="1" readonly="1"/>
</group>
<group col="2" colspan="2">
<separator string="Opening Balance" colspan="4"/>
<field name="balance_end_real" readonly="1" string="Last Closing Balance"/>
<field name="balance_start" readonly="1" string="Computed Amount"/>
<field name="balance_start" readonly="1" string="Opening Cash Control"/>
<field name="total_entry_encoding" />
</group>
<group col="2" colspan="2">
<separator string="Closing Balance" colspan="4"/>
<field name="balance_end"/>
<field name="balance_end_cash"/>
<field name="difference" />
<field name="balance_end_real" readonly="1" string="Closing Cash Control"/>
<field name="balance_end" string="Theorical Cash Closing"/>
</group>
<group col="2" colspan="2">
<separator string="Dates" colspan="4"/>
<field name="date" readonly="1"/>
<field name="closing_date" readonly="1"/>
</group>
</group>
<group col="8" colspan="4">
<field name="state" widget="statusbar" statusbar_visible="draft,confirm" colspan="4"/>
<button name="button_cancel" states="confirm,open" string="Cancel" icon="terp-gtk-stop" type="object"/>
<button name="button_confirm_cash" states="open" string="Close CashBox" icon="terp-dialog-close" type="object"/>
<button name="button_open" states="draft" string="Open CashBox" icon="gtk-go-forward" type="object"/>
</group>
</sheet>
</form>
</field>
</record>

View File

@ -57,7 +57,6 @@
- pieces: 500.0
number: 2
subtotal: 1000.0
balance_end_cash: 1120.0
-
I clicked on Close CashBox button to close the cashbox

View File

@ -30,7 +30,7 @@ class CashBox(osv.osv_memory):
for record in records:
if not record.journal_id.internal_account_id:
raise osv.except_osv(_('Error !'),
_('Please check that Internal Transfers Account is set to %s') % (record.journal_id.name,))
_("Please check that the field 'Internal Transfers Account' is set on the payment method '%s'.") % (record.journal_id.name,))
self._create_bank_statement_line(cr, uid, box, record, context=context)

View File

@ -218,7 +218,7 @@
<field name="type">form</field>
<field name="inherit_id" ref="account.view_bank_statement_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page[@name='statement_line_ids']/field[@name='line_ids']/tree/field[@name='amount']" position="after">
<xpath expr="//notebook/page[@name='statement_line_ids']/field[@name='line_ids']/tree/field[@name='amount']" position="after">
<field name="voucher_id" context="{'line_type': type, 'default_type': amount &lt; 0 and 'payment' or 'receipt', 'type': amount &lt; 0 and 'payment' or 'receipt', 'default_partner_id': partner_id, 'default_journal_id': parent.journal_id, 'default_amount': abs(amount), 'default_reference': ref, 'default_date': date, 'default_name': name}"/>
</xpath>
</field>
@ -230,7 +230,7 @@
<field name="type">form</field>
<field name="inherit_id" ref="account.view_bank_statement_form"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page[@name='statement_line_ids']/field[@name='line_ids']/form/field[@name='sequence']" position="before">
<xpath expr="//notebook/page[@name='statement_line_ids']/field[@name='line_ids']/form/field[@name='sequence']" position="before">
<field name="voucher_id" context="{'line_type': type, 'default_type': amount &lt; 0 and 'payment' or 'receipt', 'type': amount &lt; 0 and 'payment' or 'receipt', 'default_partner_id': partner_id, 'default_journal_id': parent.journal_id, 'default_amount': abs(amount), 'default_reference': ref, 'default_date': date, 'default_name': name}"/>
</xpath>
</field>
@ -241,7 +241,7 @@
<field name="type">form</field>
<field name="inherit_id" ref="account.view_bank_statement_form2"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='amount']" position="after">
<xpath expr="//field[@name='line_ids']/tree/field[@name='amount']" position="after">
<field name="voucher_id" context="{'line_type': type, 'default_type': amount &lt; 0 and 'payment' or 'receipt', 'type': amount &lt; 0 and 'payment' or 'receipt', 'default_partner_id': partner_id, 'default_journal_id': parent.journal_id, 'default_amount': abs(amount), 'default_reference': ref, 'default_date': date, 'default_name': name}"/>
</xpath>
</field>
@ -253,7 +253,7 @@
<field name="type">form</field>
<field name="inherit_id" ref="account.view_bank_statement_form2"/>
<field name="arch" type="xml">
<xpath expr="/form/notebook/page/field[@name='line_ids']/form/field[@name='amount']" position="after">
<xpath expr="//field[@name='line_ids']/form/field[@name='amount']" position="after">
<field name="voucher_id" context="{'line_type': type, 'default_type': amount &lt; 0 and 'payment' or 'receipt', 'type': amount &lt; 0 and 'payment' or 'receipt', 'default_partner_id': partner_id, 'default_journal_id': parent.journal_id, 'default_amount': abs(amount), 'default_reference': ref, 'default_date': date, 'default_name': name}"/>
</xpath>
</field>

View File

@ -41,58 +41,9 @@ account_journal()
class account_cash_statement(osv.osv):
_inherit = 'account.bank.statement'
#def _equal_balance(self, cr, uid, cash_id, context=None):
# statement = self.browse(cr, uid, cash_id, context=context)
# if not statement.journal_id.check_dtls:
# return True
# if statement.journal_id.check_dtls and (statement.balance_end != statement.balance_end_cash):
# return False
# else:
# return True
def _get_cash_open_box_lines(self, cr, uid, context=None):
res = super(account_cash_statement,self)._get_cash_open_box_lines(cr, uid, context)
curr = [0.01, 0.02, 0.05, 0.10, 0.20, 0.50]
for rs in curr:
dct = {
'pieces': rs,
'number': 0
}
res.append(dct)
res.sort()
return res
def _get_default_cash_close_box_lines(self, cr, uid, context=None):
res = super(account_cash_statement,self)._get_default_cash_close_box_lines(cr, uid, context=context)
curr = [0.01, 0.02, 0.05, 0.10, 0.20, 0.50]
for rs in curr:
dct = {
'pieces': rs,
'number': 0
}
res.append(dct)
res.sort()
return res
def search(self, cr, uid, domain, offset=0, limit=None, order=None, context=None, count=False):
if not context:
context = {}
pos_session_id = context.pop('pos_session_id', False) or False
if pos_session_id and isinstance(pos_session_id, (int, long)):
session = self.pool.get('pos.session').browse(cr, uid, pos_session_id, context=context)
return [
statement.id
for order in session.order_ids
for statement in order.statement_ids
]
return super(account_cash_statement, self).search(cr, uid, domain, offset=offset, limit=limit, order=order, context=context, count=count)
_columns = {
'pos_session_id' : fields.many2one('pos.session'),
}
account_cash_statement()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -9,12 +9,11 @@
<field name="arch" type="xml">
<xpath expr="//notebook[last()]" position="inside">
<page string="Point of Sale">
<group col="6" colspan="4">
<separator colspan="6" string="Extended Configuration"/>
<group col="4" colspan="4">
<field name="journal_user"/>
<field name="opening_control" />
<field name="closing_control" />
<field name="amount_authorized_diff" />
<field name="opening_control"/>
<field name="closing_control"/>
<field name="amount_authorized_diff"/>
</group>
</page>
</xpath>

View File

@ -37,40 +37,31 @@ class pos_config(osv.osv):
_name = 'pos.config'
POS_CONFIG_STATE = [
('draft', 'Draft'),
('active', 'Active'),
('inactive', 'Inactive'),
('deprecated', 'Deprecated')
]
_columns = {
'name' : fields.char('Name', size=32,
'name' : fields.char('Point of Sale Name', size=32,
select=1,
required=True,
# readonly=True,
# states={'draft' : [('readonly', False)]}
),
'journal_ids' : fields.many2many('account.journal',
'pos_config_journal_rel',
'pos_config_id',
'journal_id',
'Payment Methods',
'Available Payment Methods',
domain="[('journal_user', '=', True )]",
# readonly=True,
# states={'draft' : [('readonly', False)]}
),
'shop_id' : fields.many2one('sale.shop', 'Shop',
required=True,
select=1,
# readonly=True,
# states={'draft' : [('readonly', False)]}
),
'journal_id' : fields.many2one('account.journal', 'Journal',
required=True,
select=1,
domain=[('type', '=', 'sale')],
# readonly=True,
# states={'draft' : [('readonly', False)]}
),
'iface_self_checkout' : fields.boolean('Self Checkout Mode'),
'iface_websql' : fields.boolean('WebSQL (to store data)'),
@ -86,39 +77,25 @@ class pos_config(osv.osv):
required=True,
readonly=True),
'sequence_id' : fields.many2one('ir.sequence', 'Sequence',
'sequence_id' : fields.many2one('ir.sequence', 'Order IDs Sequence',
readonly=True),
'user_id' : fields.many2one('res.users', 'User',
# readonly=True,
# states={'draft' : [('readonly', False)]}
),
}
def _default_sale_journal(self, cr, uid, context=None):
res = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'sale')], limit=1)
return res and res[0] or False
def _default_shop(self, cr, uid, context=None):
res = self.pool.get('sale.shop').search(cr, uid, [])
return res and res[0] or False
_defaults = {
'state' : 'draft',
'user_id' : lambda obj, cr, uid, context: uid,
'state' : POS_CONFIG_STATE[0][0],
'shop_id': _default_shop,
'journal_id': _default_sale_journal
}
def _check_only_one_cash_journal(self, cr, uid, ids, context=None):
for record in self.browse(cr, uid, ids, context=context):
has_cash_journal = False
for journal in record.journal_ids:
if journal.type == 'cash':
if has_cash_journal:
return False
else:
has_cash_journal = True
return True
_constraints = [
(_check_only_one_cash_journal, "You should have only one Cash Journal !", ['journal_id']),
]
def set_draft(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state' : 'draft'}, context=context)
def set_active(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state' : 'active'}, context=context)
@ -129,44 +106,16 @@ class pos_config(osv.osv):
return self.write(cr, uid, ids, {'state' : 'deprecated'}, context=context)
def create(self, cr, uid, values, context=None):
proxy = self.pool.get('ir.sequence.type')
sequence_values = dict(
code='pos_%s_sequence' % values['name'].lower(),
name='POS %s Sequence' % values['name'],
)
proxy.create(cr, uid, sequence_values, context=context)
proxy = self.pool.get('ir.sequence')
sequence_values = dict(
code='pos_%s_sequence' % values['name'].lower(),
name='POS %s Sequence' % values['name'],
padding=4,
prefix="%s/%%(year)s/%%(month)s/%%(day)s/" % values['name'],
name='PoS %s' % values['name'],
padding=5,
prefix="%s/" % values['name'],
)
sequence_id = proxy.create(cr, uid, sequence_values, context=context)
values['sequence_id'] = sequence_id
return super(pos_config, self).create(cr, uid, values, context=context)
def write(self, cr, uid, ids, values, context=None):
for obj in self.browse(cr, uid, ids, context=context):
if obj.sequence_id and values.get('name', False):
prefixes = obj.sequence_id.prefix.split('/')
if len(prefixes) >= 4 and prefixes[0] == obj.name:
prefixes[0] = values['name']
sequence_values = dict(
code='pos_%s_sequence' % values['name'].lower(),
name='POS %s Sequence' % values['name'],
prefix="/".join(prefixes),
)
obj.sequence_id.write(sequence_values)
return super(pos_config, self).write(cr, uid, ids, values, context=context)
def unlink(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context):
if obj.sequence_id:
@ -189,25 +138,14 @@ class pos_session(osv.osv):
def _compute_cash_register_id(self, cr, uid, ids, fieldnames, args, context=None):
result = dict.fromkeys(ids, False)
for record in self.browse(cr, uid, ids, context=context):
cash_register_id = False
for bank_statement in record.statement_ids:
if bank_statement.journal_id.type == 'cash':
cash_register_id = bank_statement.id
for st in record.statement_ids:
if st.journal_id.type == 'cash':
result[record.id] = st.id
break
result[record.id] = cash_register_id
return result
def _compute_show_closing_control(self, cr, uid, ids, fieldnames, args, context=None):
result = dict.fromkeys(ids, False)
for session in self.browse(cr, uid, ids, context=context):
result[session.id] = any(journal.closing_control == True for journal in session.config_id.journal_ids)
return result
_columns = {
'config_id' : fields.many2one('pos.config', 'PoS',
'config_id' : fields.many2one('pos.config', 'Point of Sale',
required=True,
select=1,
domain="[('state', '=', 'active')]",
@ -215,13 +153,13 @@ class pos_session(osv.osv):
# states={'draft' : [('readonly', False)]}
),
'name' : fields.char('Session Sequence', size=32,
'name' : fields.char('Session ID', size=32,
required=True,
select=1,
# readonly=True,
# states={'draft' : [('readonly', False)]}
),
'user_id' : fields.many2one('res.users', 'User',
'user_id' : fields.many2one('res.users', 'Responsible',
required=True,
select=1,
# readonly=True,
@ -242,10 +180,6 @@ class pos_session(osv.osv):
'opening_details_ids' : fields.related('cash_register_id', 'opening_details_ids',
type='one2many', relation='account.cashbox.line',
string='CashBox Lines'),
'closing_details_ids' : fields.related('cash_register_id', 'closing_details_ids',
type='one2many', relation='account.cashbox.line',
string='CashBox Lines'),
'details_ids' : fields.related('cash_register_id', 'details_ids',
type='one2many', relation='account.cashbox.line',
string='CashBox Lines'),
@ -276,10 +210,6 @@ class pos_session(osv.osv):
digits_compute=dp.get_precision('Account'),
string="Computed Balance",
readonly=True),
'cash_register_balance_end_cash' : fields.related('cash_register_id', 'balance_end_cash',
string='Closing Balance',
help="Closing balance based on cashBox",
readonly=True),
'cash_register_difference' : fields.related('cash_register_id', 'difference',
type='float',
string='Difference',
@ -293,7 +223,6 @@ class pos_session(osv.osv):
'order_ids' : fields.one2many('pos.order', 'session_id', 'Orders'),
'statement_ids' : fields.one2many('account.bank.statement', 'pos_session_id', 'Bank Statement', readonly=True),
'show_closing_control': fields.function(_compute_show_closing_control, method=True, type='boolean', string='Show Closing Control Button'),
}
_defaults = {
@ -311,34 +240,27 @@ class pos_session(osv.osv):
# open if there is no session in 'opening_control', 'opened', 'closing_control' for one user
domain = [
('state', '!=', 'closed'),
('user_id', '=', uid),
('id', '!=', session.id),
('user_id', '=', uid)
]
count = self.search_count(cr, uid, domain, context=context)
if count:
if count>1:
return False
return True
def _check_pos_config(self, cr, uid, ids, context=None):
for session in self.browse(cr, uid, ids, context=None):
domain = [
('state', '!=', 'closed'),
('config_id', '=', session.config_id.id),
('id', '!=', session.id),
('config_id', '=', session.config_id.id)
]
count = self.search_count(cr, uid, domain, context=context)
if count:
if count>1:
return False
return True
_constraints2 = [
(_check_unicity, "You can create a new session, you have an existing and non closed session !", ['user_id', 'state']),
(_check_pos_config, "There is an existing session for the PoS Config", ['config_id']),
_constraints = [
(_check_unicity, "You can not create two active sessions with the same responsible!", ['user_id', 'state']),
(_check_pos_config, "You can not create two active sessions related to the same point of sale!", ['config_id']),
]
def create(self, cr, uid, values, context=None):
@ -352,17 +274,15 @@ class pos_session(osv.osv):
for journal in pos_config.journal_ids:
bank_values = {
'journal_id' : journal.id,
'user_id' : pos_config.user_id and pos_config.user_id.id or uid,
'user_id' : uid,
}
statement_id = self.pool.get('account.bank.statement').create(cr, uid, bank_values, context=context)
bank_statement_ids.append(statement_id)
bank_statement_ids.append(statement_id)
values.update({
'name' : pos_config.sequence_id._next(),
'statement_ids' : [(6, 0, bank_statement_ids)]
})
})
return super(pos_session, self).create(cr, uid, values, context=context)
@ -372,15 +292,6 @@ class pos_session(osv.osv):
statement.unlink(context=context)
return True
def on_change_config(self, cr, uid, ids, config_id, context=None):
result = dict(value=dict())
if not config_id:
result['value']['user_id'] = uid
else:
result['value']['user_id'] = self.pool.get('pos.config').browse(cr, uid, config_id, context=context).user_id.id
return result
def wkf_action_open(self, cr, uid, ids, context=None):
# si pas de date start_at, je balance une date, sinon on utilise celle de l'utilisateur
for record in self.browse(cr, uid, ids, context=context):
@ -388,23 +299,49 @@ class pos_session(osv.osv):
if not record.start_at:
values['start_at'] = time.strftime('%Y-%m-%d %H:%M:%S')
values['state'] = 'opened'
record.write(values, context=context)
for st in record.statement_ids:
st.button_open(context=context)
return True
def wkf_action_closing_control(self, cr, uid, ids, context=None):
# Close CashBox
for record in self.browse(cr, uid, ids, context=context):
for st in record.statement_ids:
getattr(st, 'button_confirm_%s' % st.journal_id.type)(context=context)
return self.write(cr, uid, ids, {'state' : 'closing_control', 'stop_at' : time.strftime('%Y-%m-%d %H:%M:%S')}, context=context)
def wkf_action_close(self, cr, uid, ids, context=None):
# Close CashBox
bsl = self.pool.get('account.bank.statement.line')
for record in self.browse(cr, uid, ids, context=context):
for st in record.statement_ids:
if abs(st.difference) > st.journal_id.amount_authorized_diff:
raise osv.except_osv( _('Error !'),
_("Your ending balance is too different from the theorical cash closing (%.2f), the maximum allowed is: %.2f.") % (st.difference, st.journal_id.amount_authorized_diff))
if st.difference:
if st.difference > 0.0:
name= _('Point of Sale Profit')
account_id = st.journal_id.profit_account_id.id
else:
account_id = st.journal_id.loss_account_id.id
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,))
bsl.create(cr, uid, {
'statement_id': st.id,
'amount': st.difference,
'ref': record.name,
'name': name,
'account_id': account_id
}, context=context)
print {
'statement_id': st.id,
'amount': st.difference,
'ref': record.name,
'name': name,
'account_id': account_id
}
# Create lines
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)
@ -457,7 +394,7 @@ class pos_session(osv.osv):
if not pos_config_ids:
raise osv.except_osv(_('Error !'),
_('There is no active PoS Config for this User %s') % current_user.name)
_('There is no active Point of Sale Config for this User %s') % current_user.name)
config = pos_config_proxy.browse(cr, uid, pos_config_ids[0], context=context)
@ -472,24 +409,10 @@ class pos_session(osv.osv):
session_id = self.create(cr, uid, values, context=context)
wkf_service = netsvc.LocalService('workflow')
wkf_service.trg_validate(uid, 'pos.session', session_id, 'opening_control', cr)
return session_id
pos_session()
class pos_config_journal(osv.osv):
""" Point of Sale journal configuration"""
_name = 'pos.config.journal'
_description = "Journal Configuration"
_columns = {
'name': fields.char('Description', size=64),
'code': fields.char('Code', size=64),
'journal_id': fields.many2one('account.journal', "Journal")
}
pos_config_journal()
class pos_order(osv.osv):
_name = "pos.order"
_description = "Point of Sale"
@ -555,14 +478,6 @@ class pos_order(osv.osv):
res[order.id]['amount_total'] = cur_obj.round(cr, uid, cur, val1)
return res
def _default_sale_journal(self, cr, uid, context=None):
res = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'sale')], limit=1)
return res and res[0] or False
def _default_shop(self, cr, uid, context=None):
res = self.pool.get('sale.shop').search(cr, uid, [])
return res and res[0] or False
def copy(self, cr, uid, id, default=None, context=None):
if not default:
default = {}
@ -581,9 +496,8 @@ class pos_order(osv.osv):
_columns = {
'name': fields.char('Order Ref', size=64, required=True, readonly=True),
'company_id':fields.many2one('res.company', 'Company', required=True, readonly=True),
'shop_id': fields.many2one('sale.shop', 'Shop', required=True,
states={'draft': [('readonly', False)]}, readonly=True),
'date_order': fields.datetime('Date Ordered', readonly=True, select=True),
'shop_id': fields.related('session_id', 'config_id', 'shop_id', relation='sale.shop', type='many2one', string='Shop', store=True, readonly=True),
'date_order': fields.datetime('Order Date', readonly=True, select=True),
'user_id': fields.many2one('res.users', 'Connected Salesman', help="Person who uses the the cash register. It could be a reliever, a student or an interim employee."),
'amount_tax': fields.function(_amount_all, string='Taxes', digits_compute=dp.get_precision('Point Of Sale'), multi='all'),
'amount_total': fields.function(_amount_all, string='Total', multi='all'),
@ -613,9 +527,15 @@ class pos_order(osv.osv):
'picking_id': fields.many2one('stock.picking', 'Picking', readonly=True),
'note': fields.text('Internal Notes'),
'nb_print': fields.integer('Number of Print', readonly=True),
'sale_journal': fields.many2one('account.journal', 'Journal', required=True, states={'draft': [('readonly', False)]}, readonly=True),
'sale_journal': fields.related('session_id', 'config_id', 'journal_id', relation='sale.journal', type='many2one', string='Sale Journal', store=True, readonly=True),
}
def _default_session(self, cr, uid, context=None):
so = self.pool.get('pos.session')
session_ids = so.search(cr, uid, [('state','=', 'opened'), ('user_id','=',uid)], context=context)
return session_ids and session_ids[0] or False
def _default_pricelist(self, cr, uid, context=None):
res = self.pool.get('sale.shop').search(cr, uid, [], context=context)
if res:
@ -629,9 +549,8 @@ class pos_order(osv.osv):
'name': '/',
'date_order': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'nb_print': 0,
'session_id': _default_session,
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
'sale_journal': _default_sale_journal,
'shop_id': _default_shop,
'pricelist_id': _default_pricelist,
}
@ -702,18 +621,6 @@ class pos_order(osv.osv):
picking_obj.force_assign(cr, uid, [picking_id], context)
return True
def set_to_draft(self, cr, uid, ids, *args):
if not len(ids):
return False
for order in self.browse(cr, uid, ids, context=context):
if order.state != 'cancel':
raise osv.except_osv(_('Error!'), _('In order to set to draft a sale, it must be cancelled.'))
self.write(cr, uid, ids, {'state': 'draft'})
wf_service = netsvc.LocalService("workflow")
for i in ids:
wf_service.trg_create(uid, 'pos.order', i, cr)
return True
def cancel_order(self, cr, uid, ids, context=None):
""" Changes order state to cancel
@return: True
@ -1182,7 +1089,7 @@ pos_order_line()
class pos_category(osv.osv):
_name = 'pos.category'
_description = "PoS Category"
_description = "Point of Sale Category"
_order = "sequence, name"
def _check_recursion(self, cr, uid, ids, context=None):
level = 100
@ -1248,9 +1155,9 @@ class product_product(osv.osv):
return result
_columns = {
'income_pdt': fields.boolean('PoS Cash Input', help="This is a product you can use to put cash into a statement for the point of sale backend."),
'expense_pdt': fields.boolean('PoS Cash Output', help="This is a product you can use to take cash from a statement for the point of sale backend, exemple: money lost, transfer to bank, etc."),
'pos_categ_id': fields.many2one('pos.category','PoS Category',
'income_pdt': fields.boolean('Point of Sale Cash In', help="This is a product you can use to put cash into a statement for the point of sale backend."),
'expense_pdt': fields.boolean('Point of Sale Cash Out', help="This is a product you can use to take cash from a statement for the point of sale backend, exemple: money lost, transfer to bank, etc."),
'pos_categ_id': fields.many2one('pos.category','Point of Sale Category',
help="If you want to sell this product through the point of sale, select the category it belongs to."),
'product_image_small': fields.function(_get_small_image, string='Small Image', type="binary",
store = {

View File

@ -16,16 +16,27 @@
<field name="model">pos.order</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="PoS Orders">
<group col="7" colspan="4">
<field name="session_id" required="1" />
<form string="Point of Sale Orders" layout="manual">
<div class="oe_form_topbar">
<button name="%(action_pos_payment)d" string="Payment" icon="gtk-apply" type="action" states="draft" context="{'pos_session_id' : session_id}"/>
<button name="action_invoice" string="Invoice" icon="gtk-apply" type="object" states="paid" attrs="{'readonly': [('partner_id','=',False)]}"/>
<button name="refund" string="Return Products" type="object" icon="gtk-ok"
attrs="{'invisible':[('state','=','draft')]}"/>
<button name="%(action_report_pos_receipt)d" string="Reprint" icon="gtk-print" type="action" states="paid,done,invoiced"/>
<div class="oe_right">
<field name="state" nolabel="1" widget="statusbar" statusbar_visible="draft,paid,done" statusbar_colors='{"cancel":"red"}'/>
</div>
</div>
<sheet layout="auto">
<group col="4" colspan="4">
<field name="name"/>
<field name="date_order"/>
<field name="session_id" required="1" />
<field name="partner_id" on_change="onchange_partner_id(partner_id)" context="{'search_default_customer':1}" attrs="{'readonly': [('state','=','invoiced')]}"/>
<button name="action_invoice" string="Invoice" icon="gtk-apply" type="object" states="paid" attrs="{'readonly': [('partner_id','=',False)]}"/>
</group>
<notebook colspan="4">
<page string="Sale Order">
<page string="Products">
<field name="lines" colspan="4" nolabel="1">
<tree string="Order lines" editable="bottom">
<field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,qty,parent.partner_id)"/>
@ -52,16 +63,8 @@
<button name="%(action_pos_discount)d" string="Discount" icon="gtk-remove" type="action" states="draft" />
</group>
<separator colspan="4"/>
<group colspan="4" col="8">
<field name="state" widget="statusbar" statusbar_visible="draft,paid,done" statusbar_colors='{"cancel":"red"}'/>
<button name="%(action_pos_payment)d" string="Payment" icon="gtk-apply" type="action" states="draft" context="{'pos_session_id' : session_id}"/>
<button name="refund" string="Return Products" type="object" icon="gtk-ok"
attrs="{'invisible':[('state','=','draft')]}"/>
<button name="%(action_report_pos_receipt)d" string="Reprint" icon="gtk-print" type="action" states="paid,done,invoiced"/>
</group>
</page>
<page string="Payment">
<page string="Payments">
<field name="statement_ids" colspan="4" nolabel="1">
<tree editable="bottom" string="Statement lines">
<field name="journal_id"/>
@ -100,11 +103,12 @@
<field colspan="4" name="note" nolabel="1"/>
</page>
</notebook>
</sheet>
</form>
</field>
</record>
<record model="ir.actions.act_window" id="action_pos_pos_form">
<field name="name">PoS Orders</field>
<field name="name">Orders</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">pos.order</field>
<field name="view_type">form</field>
@ -622,11 +626,13 @@
<field name="type">form</field>
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<field name="company_id" position="after">
<separator string="Point of Sale" colspan="2"/>
<field name="income_pdt"/>
<field name="expense_pdt"/>
</field>
<group name="misc" position="after">
<group name="pos" colspan="2" col="2">
<separator string="Point of Sale" colspan="2"/>
<field name="income_pdt"/>
<field name="expense_pdt"/>
</group>
</group>
</field>
</record>
@ -636,7 +642,7 @@
<field name="model">pos.category</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="PoS Categories">
<form string="Product PoS Categories">
<group colspan="4" col="6">
<field name="name"/>
<field name="parent_id"/>
@ -652,14 +658,14 @@
<field name="type">tree</field>
<field name="field_parent" eval="False"/>
<field name="arch" type="xml">
<tree string="PoS Categories">
<tree string="Product PoS Categories">
<field name="sequence" invisible="1"/>
<field name="complete_name"/>
</tree>
</field>
</record>
<record id="pos_category_action" model="ir.actions.act_window">
<field name="name">PoS Categories</field>
<field name="name">Product Categories</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">pos.category</field>
<field name="view_type">form</field>
@ -672,13 +678,12 @@
<menuitem name="Configuration" parent="menu_point_root"
id="menu_point_config_product" sequence="25" groups="group_pos_manager"/>
<!--
<record id="action_account_journal_form" model="ir.actions.act_window">
<field name="name">Payment Methods</field>
<field name="res_model">account.journal</field>
<field name="view_type">form</field>
<field name="view_mode">tree,form</field>
<field name="context" eval="{'default_journal_user': 1, 'default_view_id': ref('account.account_journal_bank_view'), 'default_type': 'cash'}"/>
<field name="context" eval="{'default_journal_user': 1, 'default_type': 'cash'}"/>
<field name="domain">[('journal_user','=', 1)]</field>
<field name="help">Payment methods are defined by accounting journals having the field Payment Method checked.</field>
</record>
@ -687,7 +692,6 @@
id="menu_action_account_journal_form_open"
parent="menu_point_config_product"
sequence="20"/>
-->
<record model="ir.ui.view" id="view_pos_order_tree_all_sales_lines">
<field name="name">POS Sales Lines</field>
@ -734,10 +738,8 @@
<field name="domain">[('origin','like','POS')]</field>
</record>
<menuitem name="Reporting" id="menu_point_of_sale_reporting" parent="menu_point_root" sequence="20" />
<menuitem icon="STOCK_PRINT" action="action_report_pos_details"
id="menu_pos_details" parent="menu_point_of_sale_reporting" sequence="6" />
id="menu_pos_details" parent="menu_point_rep" sequence="6" />
<record model="ir.actions.client" id="action_pos_pos">
<field name="name">Start Point of Sale</field>
@ -759,49 +761,43 @@
<field name="model">pos.config</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="PoS Configuration">
<field name="name" />
<notebook colspan="4">
<page string="Payment Methods">
<field name="journal_ids" colspan="4" nolabel="1">
<tree string="Journals">
<field name="code" />
<field name="name" />
<field name="type" />
<field name="opening_control" />
<field name="closing_control" />
</tree>
</field>
</page>
<page string="Accounting">
<separator string="Accounting" colspan="4" />
<field name="shop_id" widget="selection" />
<field name="journal_id" widget="selection" />
</page>
<page string="Interfaces">
<field name="iface_self_checkout" />
<field name="iface_websql" />
<field name="iface_led" />
<field name="iface_cashdrawer" />
<field name="iface_payment_terminal" />
<field name="iface_electronic_scale" />
<field name="iface_barscan" />
<field name="iface_vkeyboard" />
<field name="iface_print_via_proxy" />
</page>
<page string="Others">
<field name="user_id" />
<field name="sequence_id" />
</page>
</notebook>
<group colspan="4" col="6">
<field name="state" widget="statusbar" statusbar_visible="draft,active,inactive,deprecated" statusbar_colors='{"active":"green", "deprecated" : "red"}'/>
<button string="Set to Draft" name="set_draft" type="object" states="deprecated"/>
<button string="Set to Active" name="set_active" type="object" states="draft,inactive"/>
<form string="Point of Sale Configuration" layout="manual">
<div class="oe_form_topbar">
<button string="Set to Active" name="set_active" type="object" states="inactive,deprecated"/>
<button string="Set to Inactive" name="set_inactive" type="object" states="active" />
<button string="Set to Deprecated" name="set_deprecate" type="object" states="active,inactive" />
</group>
<div class="oe_right">
<field name="state" widget="statusbar" statusbar_visible="active,inactive,deprecated" statusbar_colors='{"deprecated" : "red"}' nolabel="1"/>
</div>
</div>
<sheet layout="auto">
<field name="name" placeholder="POS/0001"/>
<field name="shop_id" widget="selection" />
<field name="journal_id" widget="selection" />
<field name="sequence_id" readonly="1"/>
<separator string="Available Payment Methods" colspan="4"/>
<field name="journal_ids" colspan="4" nolabel="1">
<tree string="Journals">
<field name="code" />
<field name="name" />
<field name="type" />
<field name="opening_control" />
<field name="closing_control" />
</tree>
</field>
<separator string="Material Interfaces" colspan="4"/>
<field name="iface_self_checkout" />
<field name="iface_websql" />
<field name="iface_led" />
<field name="iface_cashdrawer" />
<field name="iface_payment_terminal" />
<field name="iface_electronic_scale" />
<field name="iface_barscan" />
<field name="iface_vkeyboard" />
<field name="iface_print_via_proxy" />
</sheet>
</form>
</field>
</record>
@ -811,10 +807,8 @@
<field name="model">pos.config</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="PoS Configuration" colors="grey:state == 'inactive'">
<tree string="Point of Sale Configuration" colors="grey:state == 'inactive'">
<field name="name" />
<field name="user_id" />
<field name="journal_id" />
<field name="shop_id" />
<field name="state" />
</tree>
@ -826,21 +820,13 @@
<field name="model">pos.config</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="PoS Config">
<search string="Point of Sale Config">
<filter string="Active" domain="[('state', '=', 'active')]" />
<filter string="Inactive" domain="[('state', '=', 'inactive')]" />
<separator orientation="vertical"/>
<field name="name" />
<field name="user_id" />
<field name="journal_id" />
<field name="shop_id" />
<newline />
<group expand="0" string="Group By...">
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by' : 'user_id'}" />
<filter string="Journal" icon="terp-folder-orange" domain="[]" context="{'group_by' : 'journal_id'}" />
<filter string="Shop" icon="terp-go-home" domain="[]" context="{'group_by' : 'shop_id'}" />
</group>
</search>
</field>
</record>
@ -854,7 +840,7 @@
domain="[('config_id', '=', active_id)]" />
<record model="ir.actions.act_window" id="action_pos_config_pos">
<field name="name">PoS Config</field>
<field name="name">Point of Sales</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">pos.config</field>
<field name="view_type">form</field>
@ -874,62 +860,65 @@
<field name="model">pos.session</field>
<field name="type">form</field>
<field name="arch" type="xml">
<form string="PoS Session">
<group colspan="4" col="6">
<field name="config_id" on_change="on_change_config(config_id)" />
<field name="name" />
<form string="Point of Sale Session" layout="manual">
<div class="oe_form_topbar">
<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" />
<div class="oe_right">
<field name="state" widget="statusbar" statusbar_visible="opening_control,opened,closing_control,closed" nolabel="1"/>
</div>
</div>
<sheet layout="auto">
<group colspan="4" col="4">
<field name="config_id"/>
<group colspan="2" col="2">
<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"/>
</group>
<newline/>
<field name="user_id" />
<field name="name" />
<newline/>
<field name="start_at" />
<field name="stop_at" />
</group>
<notebook colspan="4">
<page string="Cash">
<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', 'opened'))], 'readonly' : [('state', '=', 'opened')]}">
<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"/>
<field name="subtotal_opening" string="Opening Subtotal" sum="Total"/>
</tree>
</field>
<field name="closing_details_ids" colspan="4" nolabel="1" attrs="{'invisible' : [('state', '!=', 'closing_control')]}">
<tree string="Closing Cashbox Lines" editable="bottom">
<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" string="Opening Unit Numbers" readonly="1"/>
<field name="subtotal_opening" string="Opening Subtotal" readonly="1" />
<field name="number_closing" string="Closing Unit Numbers" on_change="on_change_sub_closing(pieces, number_closing, parent.balance_end)" />
<field name="subtotal_closing" string="Closing Subtotal"/>
</tree>
</field>
<field name="details_ids" colspan="4" nolabel="1" readonly="1" attrs="{'invisible': [('state', '!=', 'closed')]}">
<tree string="Cashbox Lines">
<field name="pieces" readonly="1" />
<field name="number_opening" string="Opening Unit Numbers"/>
<field name="subtotal_opening" string="Opening Subtotal"/>
<field name="number_closing" string="Closing Unit Numbers" />
<field name="subtotal_closing" string="Closing Subtotal"/>
<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" attrs="{'invisible' : [('state', 'in', ('closing_control'))]}">
<separator string="Opening Balance" colspan="4"/>
<field name="cash_register_balance_end_real" readonly="1" string="Last Closing Balance"/>
<field name="cash_register_balance_start" readonly="1" string="Computed Amount"/>
<field name="cash_register_total_entry_encoding" />
<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', 'in', ('opening_control', 'opened'))]}">
<separator string="Closing Balance" colspan="4"/>
<field name="cash_register_balance_end"/>
<field name="cash_register_balance_end_cash"/>
<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>
</page>
<page string="Accouting">
<separator string="Summary by Payment Methods" colspan="4"/>
<field name="statement_ids" colspan="4" nolabel="1">
<tree string="Statements">
<field name="name" />
@ -941,22 +930,9 @@
<field name="state" />
</tree>
</field>
</page>
<page string="Debug">
<field name="show_closing_control" />
</page>
</notebook>
</group>
<group colspan="4" col="5">
<field name="state" widget="statusbar" statusbar_visible="opening_control,opened,closing_control,closed" statusbar_colors='{"posted":"green"}'/>
<!-- state:opening_control -> signal:open -> state:opened -> signal:cashbox_control -> state:closing_control -> signal:close -> state:close -->
<button name="open" type="workflow" string="Open" states="opening_control"/>
<button name="cashbox_control" type="workflow" string="Cashbox Control" states="opened" />
<!--
attrs="{'invisible' : [('show_closing_control', '=', False)]}"/>
-->
<button name="close" type="workflow" string="Close" states="closing_control,opened" />
</group>
</sheet>
</form>
</field>
</record>
@ -966,7 +942,7 @@
<field name="model">pos.session</field>
<field name="type">tree</field>
<field name="arch" type="xml">
<tree string="PoS Session">
<tree string="Point of Sale Session">
<field name="config_id" />
<field name="name" />
<field name="user_id" />
@ -981,7 +957,7 @@
<field name="model">pos.session</field>
<field name="type">search</field>
<field name="arch" type="xml">
<search string="PoS Session">
<search string="Point of Sale Session">
<filter string="Open" domain="[('state', '=', 'opened')]" />
<separator orientation="vertical"/>
<filter string="Today" domain="[('start_at', '>=', time.strftime('%%Y-%%m-%%d 00:00:00'))]" />
@ -993,7 +969,7 @@
<newline />
<group expand="0" string="Group By...">
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by' : 'user_id'}" />
<filter string="PoS" domain="[]" context="{'group_by': 'user_id'}" />
<filter string="Point of Sales" domain="[]" context="{'group_by': 'user_id'}" />
</group>
</search>
</field>
@ -1001,7 +977,7 @@
<record model="ir.actions.act_window" id="action_pos_session">
<field name="name">PoS Sessions</field>
<field name="name">Point of Sale Sessions</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">pos.session</field>
<field name="view_type">form</field>
@ -1010,7 +986,7 @@
</record>
<menuitem
parent="menu_point_of_sale"
parent="menu_point_rep"
action="action_pos_session"
id="menu_pos_session"
groups="group_pos_manager"/>

View File

@ -69,13 +69,6 @@ class pos_details_summary(report_sxw.rml_parse):
0.0 )
def _get_payments(self, objects):
# gift_journal_id = None
# if ignore_gift:
# config_journal_ids = self.pool.get("pos.config.journal").search(self.cr, self.uid, [('code', '=', 'GIFT')])
# if len(config_journal_ids):
# config_journal = self.pool.get("pos.config.journal").browse(self.cr, self.uid, config_journal_ids, {})[0]
# gift_journal_id = config_journal.journal_id.id
result = {}
for obj in objects:
for statement in obj.statement_ids:
@ -136,4 +129,4 @@ report_sxw.report_sxw('report.pos.details_summary',
parser=pos_details_summary,
header='internal')
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

@ -36,20 +36,18 @@ def check_ean(eancode):
class res_users(osv.osv):
_inherit = 'res.users'
_columns = {
'ean13' : fields.char('EAN13', size=13, help="BarCode"),
'pos_config' : fields.many2one('pos.config', 'PoS Config', domain=[('state', '=', 'active')]),
'pos_config' : fields.many2one('pos.config', 'Default Point of Sale', domain=[('state', '=', 'active')]),
}
def _check_ean(self, cr, uid, ids, context=None):
return all(
check_ean(user.ean13) == True
for user in self.browse(cr, uid, ids, context=context)
)
)
_constraints = [
(_check_ean, "Error: Invalid ean code", ['ean13'],),
]

View File

@ -1,19 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<data>
<record id="res_users_form_preference_view" model="ir.ui.view">
<field name="name">res.users.form.view</field>
<field name="model">res.users</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_users_form_simple_modif" />
<field name="arch" type="xml">
<group name="preferences" position="inside">
<field name="pos_config" />
</group>
</field>
</record>
<record id="res_users_form_view" model="ir.ui.view">
<field name="name">res.users.form.view</field>
<field name="model">res.users</field>
<field name="type">form</field>
<field name="inherit_id" ref="base.view_users_form" />
<field name="arch" type="xml">
<notebook position="inside">
<page string="Point Of Sale">
<field name="ean13" />
<field name="pos_config" />
</page>
</notebook>
<notebook position="inside">
<page string="Point Of Sale">
<field name="ean13" />
<field name="pos_config" />
</page>
</notebook>
</field>
</record>
</data>
</openerp>
</data>
</openerp>

View File

@ -1,11 +1,9 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_pos_config_journal,pos.config.journal,model_pos_config_journal,group_pos_user,1,0,0,0
access_pos_order,pos.order,model_pos_order,group_pos_user,1,1,1,1
access_pos_order_line,pos.order.line,model_pos_order_line,group_pos_user,1,1,1,1
access_pos_order_manager,pos.order manager,model_pos_order,group_pos_manager,1,0,0,0
access_pos_order_line_manager,pos.order.line manager,model_pos_order_line,group_pos_manager,1,0,0,0
access_report_transaction_pos,report.transaction.pos,model_report_transaction_pos,group_pos_manager,1,1,1,1
access_pos_config_journal_manager,pos.config.journal.manager,model_pos_config_journal,group_pos_manager,1,1,1,1
access_account_journal_pos_user,account.journal pos_user,account.model_account_journal,group_pos_user,1,0,0,0
access_account_move_pos_user,account.move pos_user,account.model_account_move,group_pos_user,1,1,1,0
access_account_account_pos_user,account.account pos_user,account.model_account_account,group_pos_user,1,0,0,0
@ -66,4 +64,4 @@ access_product_pricelist_manager,product.pricelist manager,product.model_product
access_product_category_pos_manager,pos.category manager,model_pos_category,group_pos_manager,1,1,1,"1"""
access_product_category_pos_user,pos.category user,model_pos_category,group_pos_user,1,0,0,"0"""
access_pos_session_user,pos.session user,model_pos_session,group_pos_user,1,1,1,0
access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,1,1,0
access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,1,1,0

1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
access_pos_config_journal pos.config.journal model_pos_config_journal group_pos_user 1 0 0 0
2 access_pos_order pos.order model_pos_order group_pos_user 1 1 1 1
3 access_pos_order_line pos.order.line model_pos_order_line group_pos_user 1 1 1 1
4 access_pos_order_manager pos.order manager model_pos_order group_pos_manager 1 0 0 0
5 access_pos_order_line_manager pos.order.line manager model_pos_order_line group_pos_manager 1 0 0 0
6 access_report_transaction_pos report.transaction.pos model_report_transaction_pos group_pos_manager 1 1 1 1
access_pos_config_journal_manager pos.config.journal.manager model_pos_config_journal group_pos_manager 1 1 1 1
7 access_account_journal_pos_user account.journal pos_user account.model_account_journal group_pos_user 1 0 0 0
8 access_account_move_pos_user account.move pos_user account.model_account_move group_pos_user 1 1 1 0
9 access_account_account_pos_user account.account pos_user account.model_account_account group_pos_user 1 0 0 0
64 access_product_category_pos_manager pos.category manager model_pos_category group_pos_manager 1 1 1 1"
65 access_product_category_pos_user pos.category user model_pos_category group_pos_user 1 0 0 0"
66 access_pos_session_user pos.session user model_pos_session group_pos_user 1 1 1 0
67 access_pos_config_user pos.config user model_pos_config group_pos_user 1 1 1 0

View File

@ -69,7 +69,6 @@ class pos_box_entries(osv.osv_memory):
_columns = {
'name': fields.char('Reason', size=32, required=True),
#'journal_id': fields.selection(get_journal, "Cash Register", required=True, size=-1),
'journal_id': fields.many2one('account.journal', 'Cash Register', required=True, domain="[('journal_id.type', '=', 'cash')]"),
'product_id': fields.selection(_get_income_product, "Operation", required=True, size=-1),
'amount': fields.float('Amount', digits=(16, 2), required=True),

View File

@ -2,34 +2,33 @@
from osv import osv, fields
from tools.translate import _
import netsvc
class pos_session_opening(osv.osv_memory):
_name = 'pos.session.opening'
_columns = {
'pos_config_id' : fields.many2one('pos.config', 'PoS Config', required=True),
'pos_config_id' : fields.many2one('pos.config', 'Point of Sale', required=True),
'pos_session_id' : fields.many2one('pos.session', 'PoS Session'),
}
def open_session_cb(self, cr, uid, ids, context=None):
assert len(ids) == 1
assert len(ids) == 1, "you can open only one session at a time"
proxy = self.pool.get('pos.session')
wizard = self.browse(cr, uid, ids[0], context=context)
if not wizard.pos_session_id:
values = {
'user_id' : uid,
'config_id' : wizard.pos_config_id.id,
}
session_id = proxy.create(cr, uid, values, context=context)
if all(journal.opening_control == False
for journal in wizard.pos_config_id.journal_ids):
wkf_service = netsvc.LocalService('workflow')
wkf_service.trg_validate(uid, 'pos.session', session_id, 'open', cr)
return self._open_session(session_id)
return self._open_session(wizard.pos_session_id.id)
def open_existing_session_cb(self, cr, uid, ids, context=None):
assert len(ids) == 1
@ -50,30 +49,28 @@ class pos_session_opening(osv.osv_memory):
def on_change_config(self, cr, uid, ids, config_id, context=None):
if not config_id:
return {}
domain = [
('state', 'in', ('opening_control', 'opened')),
('config_id', '=', config_id),
]
proxy = self.pool.get('pos.session')
session_ids = proxy.search(cr, uid, domain, context=context)
result = {
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,
}
}
return result
def default_get(self, cr, uid, fieldnames, context=None):
current_user = self.pool.get('res.users').browse(cr, uid, uid, context=context)
so = self.pool.get('pos.session')
session_ids = so.search(cr, uid, [('state','<>','closed'), ('user_id','=',uid)], context=context)
if session_ids:
result = so.browse(cr, uid, session_ids[0], context=context).config_id.id
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
result = {
'pos_config_id' : current_user.pos_config and current_user.pos_config.id or False,
return {
'pos_config_id' : result,
'pos_session_id': session_ids and session_ids[0] or False
}
return result
pos_session_opening()
pos_session_opening()

View File

@ -5,19 +5,17 @@
<field name="name">pos.session.opening.form.view</field>
<field name="model">pos.session.opening</field>
<field name="arch" type="xml">
<form string="PoS Session Opening">
<separator string="Could you select a Point of Sale ?" colspan="4" />
<field name="pos_config_id" on_change="on_change_config(pos_config_id)" />
<field name="pos_session_id" invisible="1" />
<group colspan="4" col="3">
<form string="PoS Session Opening" layout="auto">
<separator string="Select your Point of Sale" colspan="4" />
<field name="pos_config_id" on_change="on_change_config(pos_config_id)" widget="selection"/>
<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"
confirm="Are you sure to open this existing session?"
attrs="{'invisible' : [('pos_session_id', '=', False)]}"
/>
<button name="open_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', '&lt;&gt;', False)]}"
/>
</group>
</form>
@ -25,7 +23,7 @@
</record>
<record id="action_pos_session_opening" model="ir.actions.act_window">
<field name="name">PoS Session Opening</field>
<field name="name">Sessions</field>
<field name="type">ir.actions.act_window</field>
<field name="res_model">pos.session.opening</field>
<field name="view_type">form</field>
@ -33,4 +31,4 @@
<field name="target">new</field>
</record>
</data>
</openerp>
</openerp>

View File

@ -283,7 +283,7 @@
<field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml">
<group name="misc" position="after">
<group col="2" colspan="2" attrs="{'invisible':[('type', '=', 'service')]}">
<group col="2" colspan="4" attrs="{'invisible':[('type', '=', 'service')]}">
<separator string="Minimum Stock Rules" colspan="2"/>
<field name="orderpoint_ids" context="{'default_product_uom': uom_id}" nolabel="1">
<tree string="Minimum Stock Rule" editable="bottom">