[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 return False
def _end_balance(self, cursor, user, ids, name, attr, context=None): 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 = {} res = {}
for statement in self.browse(cursor, user, ids, context=context):
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:
res[statement.id] = statement.balance_start res[statement.id] = statement.balance_start
currency_id = statement.currency.id for line in statement.line_ids:
for line in statement.move_line_ids: res[statement.id] += line.amount
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)
return res return res
def _get_period(self, cr, uid, context=None): def _get_period(self, cr, uid, context=None):
@ -122,7 +97,7 @@ class account_bank_statement(osv.osv):
_description = "Bank Statement" _description = "Bank Statement"
_columns = { _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 '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, 'journal_id': fields.many2one('account.journal', 'Journal', required=True,
readonly=True, states={'draft':[('readonly',False)]}), readonly=True, states={'draft':[('readonly',False)]}),
'period_id': fields.many2one('account.period', 'Period', required=True, 'period_id': fields.many2one('account.period', 'Period', required=True,
@ -133,7 +108,7 @@ class account_bank_statement(osv.osv):
states={'confirm': [('readonly', True)]}), states={'confirm': [('readonly', True)]}),
'balance_end': fields.function(_end_balance, 'balance_end': fields.function(_end_balance,
store = { 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), 'account.bank.statement.line': (_get_statement, ['amount'], 10),
}, },
string="Computed Balance", help='Balance as calculated based on Starting Balance and transaction lines'), 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): def balance_check(self, cr, uid, st_id, journal_type='bank', context=None):
st = self.browse(cr, uid, st_id, context=context) 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 !'), 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)) _('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 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')), 'pieces': fields.float('Unit of Currency', digits_compute=dp.get_precision('Account')),
'number_opening' : fields.integer('Number of Units', help='Opening Unit Numbers'), 'number_opening' : fields.integer('Number of Units', help='Opening Unit Numbers'),
'number_closing' : fields.integer('Number of Units', help='Closing 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_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='Subtotal Closing', 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'), 'bank_statement_id' : fields.many2one('account.bank.statement', ondelete='cascade'),
} }
@ -72,36 +72,26 @@ class account_cash_statement(osv.osv):
_inherit = 'account.bank.statement' _inherit = 'account.bank.statement'
def _get_starting_balance(self, cr, uid, ids, context=None): def _update_balances(self, cr, uid, ids, context=None):
"""
""" Find starting balance Set starting and ending balances according to pieces count
@param name: Names of fields.
@param arg: User defined arguments
@return: Dictionary of values.
""" """
res = {} res = {}
print 'Updating'
for statement in self.browse(cr, uid, ids, context=context): 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 continue
res[statement.id] = { start = end = 0
'balance_start': sum((line.pieces * line.number_opening for line in statement.details_ids:
for line in statement.details_ids), 0.0) start += line.subtotal_opening
end += line.subtotal_closing
data = {
'balance_start': start,
'balance_end_real': end,
} }
res[statement.id] = data
print "_get_starting_balance: %r" % (res,) print statement.id, data
return res super(account_cash_statement, self).write(cr, uid, [statement.id], data, context=context)
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,)
return res return res
def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None): def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None):
@ -114,7 +104,6 @@ class account_cash_statement(osv.osv):
res = {} res = {}
for statement in self.browse(cr, uid, ids, context=context): for statement in self.browse(cr, uid, ids, context=context):
res[statement.id] = sum((line.amount for line in statement.line_ids), 0.0) res[statement.id] = sum((line.amount for line in statement.line_ids), 0.0)
print "_get_sum_entry_encoding: %r" % (res,)
return res return res
def _get_company(self, cr, uid, context=None): 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, []) company_id = company_pool.search(cr, uid, [])
return company_id and company_id[0] or False return company_id and company_id[0] or False
def _get_cash_open_box_lines(self, cr, uid, context=None): def _get_statement_from_line(self, cr, uid, ids, 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):
result = {} result = {}
for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context): for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
result[line.statement_id.id] = True result[line.statement_id.id] = True
@ -192,83 +125,46 @@ class account_cash_statement(osv.osv):
result = dict.fromkeys(ids, 0.0) result = dict.fromkeys(ids, 0.0)
for obj in self.browse(cr, uid, ids, context=context): 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 return result
_columns = { _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 = { store = {
'account.bank.statement': (lambda self, cr, uid, ids, context=None: ids, ['line_ids','move_line_ids'], 10), '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"), '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'), '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'), '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'), 'closing_details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='Closing Cashbox Lines'),
'user_id': fields.many2one('res.users', 'Responsible', required=False), 'user_id': fields.many2one('res.users', 'Responsible', required=False),
'difference' : fields.function(_compute_difference, method=True, string="Difference", type="float"), 'difference' : fields.function(_compute_difference, method=True, string="Difference", type="float"),
} }
_defaults = { _defaults = {
'state': 'draft', 'state': 'draft',
'date': lambda self, cr, uid, context={}: context.get('date', time.strftime("%Y-%m-%d %H:%M:%S")), '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, '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): def create(self, cr, uid, vals, context=None):
if self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context).type == 'cash': journal = False
amount_total = 0.0 if vals.get('journal_id'):
for line in vals.get('details_ids',[]): journal = self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context)
print "line: %r" % (line,) if journal and (journal.type == 'cash') and not vals.get('details_ids'):
if line and len(line)==3 and line[2]: vals['details_ids'] = []
# FIXME: If there is no piece # does not work with GTK for value in journal.cashbox_line_ids:
amount_total+= line[2].get('pieces', 0) * line[2]['number_opening'] 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) res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context)
vals.update(balance_end_real=self._compute_balance_end_real(cr, uid, vals['journal_id'], context=context)) self._update_balances(cr, uid, [res_id], context)
return res_id
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)
def write(self, cr, uid, ids, vals, context=None): 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 @return: True on success, False otherwise
""" """
super(account_cash_statement, self).write(cr, uid, ids, vals, context=context) res = super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
res = self._get_starting_balance(cr, uid, ids) self._update_balances(cr, uid, ids, context)
for rs in res: return 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
def _user_allow(self, cr, uid, statement_id, context=None): def _user_allow(self, cr, uid, statement_id, context=None):
return True return True
@ -347,7 +198,7 @@ class account_cash_statement(osv.osv):
for statement in statement_pool.browse(cr, uid, ids, context=context): for statement in statement_pool.browse(cr, uid, ids, context=context):
vals = {} vals = {}
if not self._user_allow(cr, uid, statement.id, context=context): 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 == '/': if statement.name and statement.name == '/':
c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id} 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) self.write(cr, uid, [statement.id], vals, context=context)
return True 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): def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
if journal_type == 'bank': if journal_type == 'bank':
return super(account_cash_statement, self).statement_close(cr, uid, ids, journal_type, context) 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) 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() account_cash_statement()
class account_journal(osv.osv): class account_journal(osv.osv):

View File

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

View File

@ -57,7 +57,6 @@
- pieces: 500.0 - pieces: 500.0
number: 2 number: 2
subtotal: 1000.0 subtotal: 1000.0
balance_end_cash: 1120.0
- -
I clicked on Close CashBox button to close the cashbox 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: for record in records:
if not record.journal_id.internal_account_id: if not record.journal_id.internal_account_id:
raise osv.except_osv(_('Error !'), 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) self._create_bank_statement_line(cr, uid, box, record, context=context)

View File

@ -218,7 +218,7 @@
<field name="type">form</field> <field name="type">form</field>
<field name="inherit_id" ref="account.view_bank_statement_form"/> <field name="inherit_id" ref="account.view_bank_statement_form"/>
<field name="arch" type="xml"> <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}"/> <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> </xpath>
</field> </field>
@ -230,7 +230,7 @@
<field name="type">form</field> <field name="type">form</field>
<field name="inherit_id" ref="account.view_bank_statement_form"/> <field name="inherit_id" ref="account.view_bank_statement_form"/>
<field name="arch" type="xml"> <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}"/> <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> </xpath>
</field> </field>
@ -241,7 +241,7 @@
<field name="type">form</field> <field name="type">form</field>
<field name="inherit_id" ref="account.view_bank_statement_form2"/> <field name="inherit_id" ref="account.view_bank_statement_form2"/>
<field name="arch" type="xml"> <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}"/> <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> </xpath>
</field> </field>
@ -253,7 +253,7 @@
<field name="type">form</field> <field name="type">form</field>
<field name="inherit_id" ref="account.view_bank_statement_form2"/> <field name="inherit_id" ref="account.view_bank_statement_form2"/>
<field name="arch" type="xml"> <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}"/> <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> </xpath>
</field> </field>

View File

@ -41,58 +41,9 @@ account_journal()
class account_cash_statement(osv.osv): class account_cash_statement(osv.osv):
_inherit = 'account.bank.statement' _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 = { _columns = {
'pos_session_id' : fields.many2one('pos.session'), 'pos_session_id' : fields.many2one('pos.session'),
} }
account_cash_statement() account_cash_statement()
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:

View File

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

View File

@ -37,40 +37,31 @@ class pos_config(osv.osv):
_name = 'pos.config' _name = 'pos.config'
POS_CONFIG_STATE = [ POS_CONFIG_STATE = [
('draft', 'Draft'),
('active', 'Active'), ('active', 'Active'),
('inactive', 'Inactive'), ('inactive', 'Inactive'),
('deprecated', 'Deprecated') ('deprecated', 'Deprecated')
] ]
_columns = { _columns = {
'name' : fields.char('Name', size=32, 'name' : fields.char('Point of Sale Name', size=32,
select=1, select=1,
required=True, required=True,
# readonly=True,
# states={'draft' : [('readonly', False)]}
), ),
'journal_ids' : fields.many2many('account.journal', 'journal_ids' : fields.many2many('account.journal',
'pos_config_journal_rel', 'pos_config_journal_rel',
'pos_config_id', 'pos_config_id',
'journal_id', 'journal_id',
'Payment Methods', 'Available Payment Methods',
domain="[('journal_user', '=', True )]", domain="[('journal_user', '=', True )]",
# readonly=True,
# states={'draft' : [('readonly', False)]}
), ),
'shop_id' : fields.many2one('sale.shop', 'Shop', 'shop_id' : fields.many2one('sale.shop', 'Shop',
required=True, required=True,
select=1, select=1,
# readonly=True,
# states={'draft' : [('readonly', False)]}
), ),
'journal_id' : fields.many2one('account.journal', 'Journal', 'journal_id' : fields.many2one('account.journal', 'Journal',
required=True, required=True,
select=1, select=1,
domain=[('type', '=', 'sale')], domain=[('type', '=', 'sale')],
# readonly=True,
# states={'draft' : [('readonly', False)]}
), ),
'iface_self_checkout' : fields.boolean('Self Checkout Mode'), 'iface_self_checkout' : fields.boolean('Self Checkout Mode'),
'iface_websql' : fields.boolean('WebSQL (to store data)'), 'iface_websql' : fields.boolean('WebSQL (to store data)'),
@ -86,39 +77,25 @@ class pos_config(osv.osv):
required=True, required=True,
readonly=True), readonly=True),
'sequence_id' : fields.many2one('ir.sequence', 'Sequence', 'sequence_id' : fields.many2one('ir.sequence', 'Order IDs Sequence',
readonly=True), 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 = { _defaults = {
'state' : 'draft', 'state' : POS_CONFIG_STATE[0][0],
'user_id' : lambda obj, cr, uid, context: uid, '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): def set_active(self, cr, uid, ids, context=None):
return self.write(cr, uid, ids, {'state' : 'active'}, context=context) 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) return self.write(cr, uid, ids, {'state' : 'deprecated'}, context=context)
def create(self, cr, uid, values, context=None): 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') proxy = self.pool.get('ir.sequence')
sequence_values = dict( sequence_values = dict(
code='pos_%s_sequence' % values['name'].lower(), name='PoS %s' % values['name'],
name='POS %s Sequence' % values['name'], padding=5,
padding=4, prefix="%s/" % values['name'],
prefix="%s/%%(year)s/%%(month)s/%%(day)s/" % values['name'],
) )
sequence_id = proxy.create(cr, uid, sequence_values, context=context) sequence_id = proxy.create(cr, uid, sequence_values, context=context)
values['sequence_id'] = sequence_id values['sequence_id'] = sequence_id
return super(pos_config, self).create(cr, uid, values, context=context) 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): def unlink(self, cr, uid, ids, context=None):
for obj in self.browse(cr, uid, ids, context=context): for obj in self.browse(cr, uid, ids, context=context):
if obj.sequence_id: 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): def _compute_cash_register_id(self, cr, uid, ids, fieldnames, args, context=None):
result = dict.fromkeys(ids, False) result = dict.fromkeys(ids, False)
for record in self.browse(cr, uid, ids, context=context): for record in self.browse(cr, uid, ids, context=context):
cash_register_id = False for st in record.statement_ids:
for bank_statement in record.statement_ids: if st.journal_id.type == 'cash':
if bank_statement.journal_id.type == 'cash': result[record.id] = st.id
cash_register_id = bank_statement.id
break 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 return result
_columns = { _columns = {
'config_id' : fields.many2one('pos.config', 'PoS', 'config_id' : fields.many2one('pos.config', 'Point of Sale',
required=True, required=True,
select=1, select=1,
domain="[('state', '=', 'active')]", domain="[('state', '=', 'active')]",
@ -215,13 +153,13 @@ class pos_session(osv.osv):
# states={'draft' : [('readonly', False)]} # states={'draft' : [('readonly', False)]}
), ),
'name' : fields.char('Session Sequence', size=32, 'name' : fields.char('Session ID', size=32,
required=True, required=True,
select=1, select=1,
# readonly=True, # readonly=True,
# states={'draft' : [('readonly', False)]} # states={'draft' : [('readonly', False)]}
), ),
'user_id' : fields.many2one('res.users', 'User', 'user_id' : fields.many2one('res.users', 'Responsible',
required=True, required=True,
select=1, select=1,
# readonly=True, # readonly=True,
@ -242,10 +180,6 @@ class pos_session(osv.osv):
'opening_details_ids' : fields.related('cash_register_id', 'opening_details_ids', 'opening_details_ids' : fields.related('cash_register_id', 'opening_details_ids',
type='one2many', relation='account.cashbox.line', type='one2many', relation='account.cashbox.line',
string='CashBox Lines'), 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', 'details_ids' : fields.related('cash_register_id', 'details_ids',
type='one2many', relation='account.cashbox.line', type='one2many', relation='account.cashbox.line',
string='CashBox Lines'), string='CashBox Lines'),
@ -276,10 +210,6 @@ class pos_session(osv.osv):
digits_compute=dp.get_precision('Account'), digits_compute=dp.get_precision('Account'),
string="Computed Balance", string="Computed Balance",
readonly=True), 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', 'cash_register_difference' : fields.related('cash_register_id', 'difference',
type='float', type='float',
string='Difference', string='Difference',
@ -293,7 +223,6 @@ class pos_session(osv.osv):
'order_ids' : fields.one2many('pos.order', 'session_id', 'Orders'), 'order_ids' : fields.one2many('pos.order', 'session_id', 'Orders'),
'statement_ids' : fields.one2many('account.bank.statement', 'pos_session_id', 'Bank Statement', readonly=True), '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 = { _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 # open if there is no session in 'opening_control', 'opened', 'closing_control' for one user
domain = [ domain = [
('state', '!=', 'closed'), ('state', '!=', 'closed'),
('user_id', '=', uid), ('user_id', '=', uid)
('id', '!=', session.id),
] ]
count = self.search_count(cr, uid, domain, context=context) count = self.search_count(cr, uid, domain, context=context)
if count>1:
if count:
return False return False
return True return True
def _check_pos_config(self, cr, uid, ids, context=None): def _check_pos_config(self, cr, uid, ids, context=None):
for session in self.browse(cr, uid, ids, context=None): for session in self.browse(cr, uid, ids, context=None):
domain = [ domain = [
('state', '!=', 'closed'), ('state', '!=', 'closed'),
('config_id', '=', session.config_id.id), ('config_id', '=', session.config_id.id)
('id', '!=', session.id),
] ]
count = self.search_count(cr, uid, domain, context=context) count = self.search_count(cr, uid, domain, context=context)
if count>1:
if count:
return False return False
return True return True
_constraints2 = [ _constraints = [
(_check_unicity, "You can create a new session, you have an existing and non closed session !", ['user_id', 'state']), (_check_unicity, "You can not create two active sessions with the same responsible!", ['user_id', 'state']),
(_check_pos_config, "There is an existing session for the PoS Config", ['config_id']), (_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): def create(self, cr, uid, values, context=None):
@ -352,17 +274,15 @@ class pos_session(osv.osv):
for journal in pos_config.journal_ids: for journal in pos_config.journal_ids:
bank_values = { bank_values = {
'journal_id' : journal.id, '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) 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({ values.update({
'name' : pos_config.sequence_id._next(), 'name' : pos_config.sequence_id._next(),
'statement_ids' : [(6, 0, bank_statement_ids)] 'statement_ids' : [(6, 0, bank_statement_ids)]
}) })
return super(pos_session, self).create(cr, uid, values, context=context) return super(pos_session, self).create(cr, uid, values, context=context)
@ -372,15 +292,6 @@ class pos_session(osv.osv):
statement.unlink(context=context) statement.unlink(context=context)
return True 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): 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 # 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): for record in self.browse(cr, uid, ids, context=context):
@ -388,23 +299,49 @@ class pos_session(osv.osv):
if not record.start_at: if not record.start_at:
values['start_at'] = time.strftime('%Y-%m-%d %H:%M:%S') values['start_at'] = time.strftime('%Y-%m-%d %H:%M:%S')
values['state'] = 'opened' values['state'] = 'opened'
record.write(values, context=context) record.write(values, context=context)
for st in record.statement_ids: for st in record.statement_ids:
st.button_open(context=context) st.button_open(context=context)
return True return True
def wkf_action_closing_control(self, cr, uid, ids, context=None): 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) 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): 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) self._confirm_orders(cr, uid, ids, context=context)
return self.write(cr, uid, ids, {'state' : 'closed'}, 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: if not pos_config_ids:
raise osv.except_osv(_('Error !'), 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) 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) session_id = self.create(cr, uid, values, context=context)
wkf_service = netsvc.LocalService('workflow') wkf_service = netsvc.LocalService('workflow')
wkf_service.trg_validate(uid, 'pos.session', session_id, 'opening_control', cr) wkf_service.trg_validate(uid, 'pos.session', session_id, 'opening_control', cr)
return session_id return session_id
pos_session() 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): class pos_order(osv.osv):
_name = "pos.order" _name = "pos.order"
_description = "Point of Sale" _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) res[order.id]['amount_total'] = cur_obj.round(cr, uid, cur, val1)
return res 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): def copy(self, cr, uid, id, default=None, context=None):
if not default: if not default:
default = {} default = {}
@ -581,9 +496,8 @@ class pos_order(osv.osv):
_columns = { _columns = {
'name': fields.char('Order Ref', size=64, required=True, readonly=True), 'name': fields.char('Order Ref', size=64, required=True, readonly=True),
'company_id':fields.many2one('res.company', 'Company', required=True, readonly=True), 'company_id':fields.many2one('res.company', 'Company', required=True, readonly=True),
'shop_id': fields.many2one('sale.shop', 'Shop', required=True, 'shop_id': fields.related('session_id', 'config_id', 'shop_id', relation='sale.shop', type='many2one', string='Shop', store=True, readonly=True),
states={'draft': [('readonly', False)]}, readonly=True), 'date_order': fields.datetime('Order Date', readonly=True, select=True),
'date_order': fields.datetime('Date Ordered', 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."), '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_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'), '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), 'picking_id': fields.many2one('stock.picking', 'Picking', readonly=True),
'note': fields.text('Internal Notes'), 'note': fields.text('Internal Notes'),
'nb_print': fields.integer('Number of Print', readonly=True), '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): def _default_pricelist(self, cr, uid, context=None):
res = self.pool.get('sale.shop').search(cr, uid, [], context=context) res = self.pool.get('sale.shop').search(cr, uid, [], context=context)
if res: if res:
@ -629,9 +549,8 @@ class pos_order(osv.osv):
'name': '/', 'name': '/',
'date_order': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), 'date_order': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
'nb_print': 0, '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, '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, 'pricelist_id': _default_pricelist,
} }
@ -702,18 +621,6 @@ class pos_order(osv.osv):
picking_obj.force_assign(cr, uid, [picking_id], context) picking_obj.force_assign(cr, uid, [picking_id], context)
return True 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): def cancel_order(self, cr, uid, ids, context=None):
""" Changes order state to cancel """ Changes order state to cancel
@return: True @return: True
@ -1182,7 +1089,7 @@ pos_order_line()
class pos_category(osv.osv): class pos_category(osv.osv):
_name = 'pos.category' _name = 'pos.category'
_description = "PoS Category" _description = "Point of Sale Category"
_order = "sequence, name" _order = "sequence, name"
def _check_recursion(self, cr, uid, ids, context=None): def _check_recursion(self, cr, uid, ids, context=None):
level = 100 level = 100
@ -1248,9 +1155,9 @@ class product_product(osv.osv):
return result return result
_columns = { _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."), '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('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."), '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','PoS Category', '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."), 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", 'product_image_small': fields.function(_get_small_image, string='Small Image', type="binary",
store = { store = {

View File

@ -16,16 +16,27 @@
<field name="model">pos.order</field> <field name="model">pos.order</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="PoS Orders"> <form string="Point of Sale Orders" layout="manual">
<group col="7" colspan="4"> <div class="oe_form_topbar">
<field name="session_id" required="1" /> <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="name"/>
<field name="date_order"/> <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')]}"/> <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> </group>
<notebook colspan="4"> <notebook colspan="4">
<page string="Sale Order"> <page string="Products">
<field name="lines" colspan="4" nolabel="1"> <field name="lines" colspan="4" nolabel="1">
<tree string="Order lines" editable="bottom"> <tree string="Order lines" editable="bottom">
<field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,qty,parent.partner_id)"/> <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" /> <button name="%(action_pos_discount)d" string="Discount" icon="gtk-remove" type="action" states="draft" />
</group> </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>
<page string="Payment"> <page string="Payments">
<field name="statement_ids" colspan="4" nolabel="1"> <field name="statement_ids" colspan="4" nolabel="1">
<tree editable="bottom" string="Statement lines"> <tree editable="bottom" string="Statement lines">
<field name="journal_id"/> <field name="journal_id"/>
@ -100,11 +103,12 @@
<field colspan="4" name="note" nolabel="1"/> <field colspan="4" name="note" nolabel="1"/>
</page> </page>
</notebook> </notebook>
</sheet>
</form> </form>
</field> </field>
</record> </record>
<record model="ir.actions.act_window" id="action_pos_pos_form"> <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="type">ir.actions.act_window</field>
<field name="res_model">pos.order</field> <field name="res_model">pos.order</field>
<field name="view_type">form</field> <field name="view_type">form</field>
@ -622,11 +626,13 @@
<field name="type">form</field> <field name="type">form</field>
<field name="inherit_id" ref="product.product_normal_form_view"/> <field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<field name="company_id" position="after"> <group name="misc" position="after">
<separator string="Point of Sale" colspan="2"/> <group name="pos" colspan="2" col="2">
<field name="income_pdt"/> <separator string="Point of Sale" colspan="2"/>
<field name="expense_pdt"/> <field name="income_pdt"/>
</field> <field name="expense_pdt"/>
</group>
</group>
</field> </field>
</record> </record>
@ -636,7 +642,7 @@
<field name="model">pos.category</field> <field name="model">pos.category</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="PoS Categories"> <form string="Product PoS Categories">
<group colspan="4" col="6"> <group colspan="4" col="6">
<field name="name"/> <field name="name"/>
<field name="parent_id"/> <field name="parent_id"/>
@ -652,14 +658,14 @@
<field name="type">tree</field> <field name="type">tree</field>
<field name="field_parent" eval="False"/> <field name="field_parent" eval="False"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="PoS Categories"> <tree string="Product PoS Categories">
<field name="sequence" invisible="1"/> <field name="sequence" invisible="1"/>
<field name="complete_name"/> <field name="complete_name"/>
</tree> </tree>
</field> </field>
</record> </record>
<record id="pos_category_action" model="ir.actions.act_window"> <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="type">ir.actions.act_window</field>
<field name="res_model">pos.category</field> <field name="res_model">pos.category</field>
<field name="view_type">form</field> <field name="view_type">form</field>
@ -672,13 +678,12 @@
<menuitem name="Configuration" parent="menu_point_root" <menuitem name="Configuration" parent="menu_point_root"
id="menu_point_config_product" sequence="25" groups="group_pos_manager"/> id="menu_point_config_product" sequence="25" groups="group_pos_manager"/>
<!--
<record id="action_account_journal_form" model="ir.actions.act_window"> <record id="action_account_journal_form" model="ir.actions.act_window">
<field name="name">Payment Methods</field> <field name="name">Payment Methods</field>
<field name="res_model">account.journal</field> <field name="res_model">account.journal</field>
<field name="view_type">form</field> <field name="view_type">form</field>
<field name="view_mode">tree,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="domain">[('journal_user','=', 1)]</field>
<field name="help">Payment methods are defined by accounting journals having the field Payment Method checked.</field> <field name="help">Payment methods are defined by accounting journals having the field Payment Method checked.</field>
</record> </record>
@ -687,7 +692,6 @@
id="menu_action_account_journal_form_open" id="menu_action_account_journal_form_open"
parent="menu_point_config_product" parent="menu_point_config_product"
sequence="20"/> sequence="20"/>
-->
<record model="ir.ui.view" id="view_pos_order_tree_all_sales_lines"> <record model="ir.ui.view" id="view_pos_order_tree_all_sales_lines">
<field name="name">POS Sales Lines</field> <field name="name">POS Sales Lines</field>
@ -734,10 +738,8 @@
<field name="domain">[('origin','like','POS')]</field> <field name="domain">[('origin','like','POS')]</field>
</record> </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" <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"> <record model="ir.actions.client" id="action_pos_pos">
<field name="name">Start Point of Sale</field> <field name="name">Start Point of Sale</field>
@ -759,49 +761,43 @@
<field name="model">pos.config</field> <field name="model">pos.config</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="PoS Configuration"> <form string="Point of Sale Configuration" layout="manual">
<field name="name" /> <div class="oe_form_topbar">
<notebook colspan="4"> <button string="Set to Active" name="set_active" type="object" states="inactive,deprecated"/>
<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"/>
<button string="Set to Inactive" name="set_inactive" type="object" states="active" /> <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" /> <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> </form>
</field> </field>
</record> </record>
@ -811,10 +807,8 @@
<field name="model">pos.config</field> <field name="model">pos.config</field>
<field name="type">tree</field> <field name="type">tree</field>
<field name="arch" type="xml"> <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="name" />
<field name="user_id" />
<field name="journal_id" />
<field name="shop_id" /> <field name="shop_id" />
<field name="state" /> <field name="state" />
</tree> </tree>
@ -826,21 +820,13 @@
<field name="model">pos.config</field> <field name="model">pos.config</field>
<field name="type">search</field> <field name="type">search</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="PoS Config"> <search string="Point of Sale Config">
<filter string="Active" domain="[('state', '=', 'active')]" /> <filter string="Active" domain="[('state', '=', 'active')]" />
<filter string="Inactive" domain="[('state', '=', 'inactive')]" /> <filter string="Inactive" domain="[('state', '=', 'inactive')]" />
<separator orientation="vertical"/> <separator orientation="vertical"/>
<field name="name" /> <field name="name" />
<field name="user_id" />
<field name="journal_id" />
<field name="shop_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> </search>
</field> </field>
</record> </record>
@ -854,7 +840,7 @@
domain="[('config_id', '=', active_id)]" /> domain="[('config_id', '=', active_id)]" />
<record model="ir.actions.act_window" id="action_pos_config_pos"> <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="type">ir.actions.act_window</field>
<field name="res_model">pos.config</field> <field name="res_model">pos.config</field>
<field name="view_type">form</field> <field name="view_type">form</field>
@ -874,62 +860,65 @@
<field name="model">pos.session</field> <field name="model">pos.session</field>
<field name="type">form</field> <field name="type">form</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<form string="PoS Session"> <form string="Point of Sale Session" layout="manual">
<group colspan="4" col="6"> <div class="oe_form_topbar">
<field name="config_id" on_change="on_change_config(config_id)" /> <button name="open" type="workflow" string="Validate &amp; Open Session" states="opening_control" />
<field name="name" /> <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="user_id" />
<field name="name" />
<newline/>
<field name="start_at" /> <field name="start_at" />
<field name="stop_at" /> <field name="stop_at" />
</group> <separator string="Cash Control" colspan="4"/>
<notebook colspan="4">
<page string="Cash">
<field name="cash_register_id" invisible="1" /> <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"> <tree string="Opening Cashbox Lines" editable="bottom">
<field name="pieces" readonly="1" /> <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="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> </tree>
</field> </field>
<field name="closing_details_ids" colspan="4" nolabel="1" attrs="{'invisible' : [('state', '!=', 'closing_control')]}"> <field name="details_ids" colspan="4" nolabel="1" attrs="{'invisible': [('state', '=', 'opening_control')]}">
<tree string="Closing Cashbox Lines" editable="bottom"> <tree string="Cashbox Lines" editable="bottom">
<field name="pieces" readonly="1" /> <field name="pieces" readonly="1" />
<field name="number_opening" string="Opening Unit Numbers" readonly="1"/> <field name="number_opening" readonly="1"/>
<field name="subtotal_opening" string="Opening Subtotal" readonly="1" /> <field name="subtotal_opening"/>
<field name="number_closing" string="Closing Unit Numbers" on_change="on_change_sub_closing(pieces, number_closing, parent.balance_end)" /> <field name="number_closing"/>
<field name="subtotal_closing" string="Closing Subtotal"/> <field name="subtotal_closing"/>
</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"/>
</tree> </tree>
</field> </field>
<group col="4" colspan="4"> <group col="4" colspan="4">
<group col="2" colspan="2" attrs="{'invisible' : [('state', 'in', ('closing_control'))]}"> <group col="2" colspan="2">
<separator string="Opening Balance" colspan="4"/> <separator string="Cash Balance" colspan="2"/>
<field name="cash_register_balance_end_real" readonly="1" string="Last Closing Balance"/> <field name="cash_register_balance_start" readonly="1" string="Opening Cash Control"/>
<field name="cash_register_balance_start" readonly="1" string="Computed Amount"/> <field name="cash_register_total_entry_encoding" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="+ Transactions"/>
<field name="cash_register_total_entry_encoding" /> <field name="cash_register_balance_end" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="= Theorical Cash Closing"/>
</group> </group>
<group col="2" colspan="2" attrs="{'invisible' : [('state', 'in', ('opening_control', 'opened'))]}"> <group col="2" colspan="2" attrs="{'invisible' : [('state', '=', 'opening_control')]}">
<separator string="Closing Balance" colspan="4"/> <separator string="Cash Closing Balance" colspan="2"/>
<field name="cash_register_balance_end"/> <field name="cash_register_balance_end_real"/>
<field name="cash_register_balance_end_cash"/>
<field name="cash_register_difference" /> <field name="cash_register_difference" />
</group> </group>
</group> </group>
</page> <separator string="Summary by Payment Methods" colspan="4"/>
<page string="Accouting">
<field name="statement_ids" colspan="4" nolabel="1"> <field name="statement_ids" colspan="4" nolabel="1">
<tree string="Statements"> <tree string="Statements">
<field name="name" /> <field name="name" />
@ -941,22 +930,9 @@
<field name="state" /> <field name="state" />
</tree> </tree>
</field> </field>
</page> </group>
<page string="Debug">
<field name="show_closing_control" />
</page>
</notebook>
<group colspan="4" col="5"> </sheet>
<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>
</form> </form>
</field> </field>
</record> </record>
@ -966,7 +942,7 @@
<field name="model">pos.session</field> <field name="model">pos.session</field>
<field name="type">tree</field> <field name="type">tree</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<tree string="PoS Session"> <tree string="Point of Sale Session">
<field name="config_id" /> <field name="config_id" />
<field name="name" /> <field name="name" />
<field name="user_id" /> <field name="user_id" />
@ -981,7 +957,7 @@
<field name="model">pos.session</field> <field name="model">pos.session</field>
<field name="type">search</field> <field name="type">search</field>
<field name="arch" type="xml"> <field name="arch" type="xml">
<search string="PoS Session"> <search string="Point of Sale Session">
<filter string="Open" domain="[('state', '=', 'opened')]" /> <filter string="Open" domain="[('state', '=', 'opened')]" />
<separator orientation="vertical"/> <separator orientation="vertical"/>
<filter string="Today" domain="[('start_at', '>=', time.strftime('%%Y-%%m-%%d 00:00:00'))]" /> <filter string="Today" domain="[('start_at', '>=', time.strftime('%%Y-%%m-%%d 00:00:00'))]" />
@ -993,7 +969,7 @@
<newline /> <newline />
<group expand="0" string="Group By..."> <group expand="0" string="Group By...">
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by' : 'user_id'}" /> <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> </group>
</search> </search>
</field> </field>
@ -1001,7 +977,7 @@
<record model="ir.actions.act_window" id="action_pos_session"> <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="type">ir.actions.act_window</field>
<field name="res_model">pos.session</field> <field name="res_model">pos.session</field>
<field name="view_type">form</field> <field name="view_type">form</field>
@ -1010,7 +986,7 @@
</record> </record>
<menuitem <menuitem
parent="menu_point_of_sale" parent="menu_point_rep"
action="action_pos_session" action="action_pos_session"
id="menu_pos_session" id="menu_pos_session"
groups="group_pos_manager"/> groups="group_pos_manager"/>

View File

@ -69,13 +69,6 @@ class pos_details_summary(report_sxw.rml_parse):
0.0 ) 0.0 )
def _get_payments(self, objects): 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 = {} result = {}
for obj in objects: for obj in objects:
for statement in obj.statement_ids: for statement in obj.statement_ids:
@ -136,4 +129,4 @@ report_sxw.report_sxw('report.pos.details_summary',
parser=pos_details_summary, parser=pos_details_summary,
header='internal') 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): class res_users(osv.osv):
_inherit = 'res.users' _inherit = 'res.users'
_columns = { _columns = {
'ean13' : fields.char('EAN13', size=13, help="BarCode"), '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): def _check_ean(self, cr, uid, ids, context=None):
return all( return all(
check_ean(user.ean13) == True check_ean(user.ean13) == True
for user in self.browse(cr, uid, ids, context=context) for user in self.browse(cr, uid, ids, context=context)
) )
_constraints = [ _constraints = [
(_check_ean, "Error: Invalid ean code", ['ean13'],), (_check_ean, "Error: Invalid ean code", ['ean13'],),
] ]

View File

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

View File

@ -1,11 +1,9 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 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,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_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_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_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_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_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_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 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_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_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_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 = { _columns = {
'name': fields.char('Reason', size=32, required=True), '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')]"), '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), 'product_id': fields.selection(_get_income_product, "Operation", required=True, size=-1),
'amount': fields.float('Amount', digits=(16, 2), required=True), 'amount': fields.float('Amount', digits=(16, 2), required=True),

View File

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

View File

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

View File

@ -283,7 +283,7 @@
<field name="inherit_id" ref="product.product_normal_form_view"/> <field name="inherit_id" ref="product.product_normal_form_view"/>
<field name="arch" type="xml"> <field name="arch" type="xml">
<group name="misc" position="after"> <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"/> <separator string="Minimum Stock Rules" colspan="2"/>
<field name="orderpoint_ids" context="{'default_product_uom': uom_id}" nolabel="1"> <field name="orderpoint_ids" context="{'default_product_uom': uom_id}" nolabel="1">
<tree string="Minimum Stock Rule" editable="bottom"> <tree string="Minimum Stock Rule" editable="bottom">