[MERGE] point_of_sale: merging pos backend updates from fp
bzr revid: fva@openerp.com-20120514140751-mqmhjf9oejyub3x5
This commit is contained in:
commit
e4b1260ace
|
@ -716,6 +716,7 @@ class account_journal(osv.osv):
|
|||
_name = "account.journal"
|
||||
_description = "Journal"
|
||||
_columns = {
|
||||
'with_last_closing_balance' : fields.boolean('Opening With Last Closing Balance'),
|
||||
'name': fields.char('Journal Name', size=64, required=True),
|
||||
'code': fields.char('Code', size=5, required=True, help="The code will be displayed on reports."),
|
||||
'type': fields.selection([('sale', 'Sale'),('sale_refund','Sale Refund'), ('purchase', 'Purchase'), ('purchase_refund','Purchase Refund'), ('cash', 'Cash'), ('bank', 'Bank and Cheques'), ('general', 'General'), ('situation', 'Opening/Closing Situation')], 'Type', size=32, required=True,
|
||||
|
@ -746,6 +747,7 @@ class account_journal(osv.osv):
|
|||
}
|
||||
|
||||
_defaults = {
|
||||
'with_last_closing_balance' : False,
|
||||
'user_id': lambda self, cr, uid, context: uid,
|
||||
'company_id': lambda self, cr, uid, c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
|
||||
}
|
||||
|
|
|
@ -53,36 +53,11 @@ class account_bank_statement(osv.osv):
|
|||
return False
|
||||
|
||||
def _end_balance(self, cursor, user, ids, name, attr, context=None):
|
||||
res_currency_obj = self.pool.get('res.currency')
|
||||
res_users_obj = self.pool.get('res.users')
|
||||
res = {}
|
||||
|
||||
company_currency_id = res_users_obj.browse(cursor, user, user,
|
||||
context=context).company_id.currency_id.id
|
||||
|
||||
statements = self.browse(cursor, user, ids, context=context)
|
||||
for statement in statements:
|
||||
for statement in self.browse(cursor, user, ids, context=context):
|
||||
res[statement.id] = statement.balance_start
|
||||
currency_id = statement.currency.id
|
||||
for line in statement.move_line_ids:
|
||||
if line.debit > 0:
|
||||
if line.account_id.id == \
|
||||
statement.journal_id.default_debit_account_id.id:
|
||||
res[statement.id] += res_currency_obj.compute(cursor,
|
||||
user, company_currency_id, currency_id,
|
||||
line.debit, context=context)
|
||||
else:
|
||||
if line.account_id.id == \
|
||||
statement.journal_id.default_credit_account_id.id:
|
||||
res[statement.id] -= res_currency_obj.compute(cursor,
|
||||
user, company_currency_id, currency_id,
|
||||
line.credit, context=context)
|
||||
|
||||
if statement.state in ('draft', 'open'):
|
||||
for line in statement.line_ids:
|
||||
res[statement.id] += line.amount
|
||||
for r in res:
|
||||
res[r] = round(res[r], 2)
|
||||
for line in statement.line_ids:
|
||||
res[statement.id] += line.amount
|
||||
return res
|
||||
|
||||
def _get_period(self, cr, uid, context=None):
|
||||
|
@ -122,7 +97,7 @@ class account_bank_statement(osv.osv):
|
|||
_description = "Bank Statement"
|
||||
_columns = {
|
||||
'name': fields.char('Name', size=64, required=True, states={'draft': [('readonly', False)]}, readonly=True, help='if you give the Name other then /, its created Accounting Entries Move will be with same name as statement name. This allows the statement entries to have the same references than the statement itself'), # readonly for account_cash_statement
|
||||
'date': fields.date('Date', required=True, states={'confirm': [('readonly', True)]}, select=True),
|
||||
'date': fields.date('Creation Date', required=True, states={'confirm': [('readonly', True)]}, select=True),
|
||||
'journal_id': fields.many2one('account.journal', 'Journal', required=True,
|
||||
readonly=True, states={'draft':[('readonly',False)]}),
|
||||
'period_id': fields.many2one('account.period', 'Period', required=True,
|
||||
|
@ -133,7 +108,7 @@ class account_bank_statement(osv.osv):
|
|||
states={'confirm': [('readonly', True)]}),
|
||||
'balance_end': fields.function(_end_balance,
|
||||
store = {
|
||||
'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids'], 10),
|
||||
'account.bank.statement': (lambda self, cr, uid, ids, c={}: ids, ['line_ids','move_line_ids','balance_start'], 10),
|
||||
'account.bank.statement.line': (_get_statement, ['amount'], 10),
|
||||
},
|
||||
string="Computed Balance", help='Balance as calculated based on Starting Balance and transaction lines'),
|
||||
|
@ -303,7 +278,7 @@ class account_bank_statement(osv.osv):
|
|||
|
||||
def balance_check(self, cr, uid, st_id, journal_type='bank', context=None):
|
||||
st = self.browse(cr, uid, st_id, context=context)
|
||||
if not ((abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001) or (abs((st.balance_end or 0.0) - st.balance_end_cash) < 0.0001)):
|
||||
if not ((abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001) or (abs((st.balance_end or 0.0) - st.balance_end_real) < 0.0001)):
|
||||
raise osv.except_osv(_('Error !'),
|
||||
_('The statement balance is incorrect !\nThe expected balance (%.2f) is different than the computed one. (%.2f)') % (st.balance_end_real, st.balance_end))
|
||||
return True
|
||||
|
@ -374,15 +349,11 @@ class account_bank_statement(osv.osv):
|
|||
return self.write(cr, uid, done, {'state':'draft'}, context=context)
|
||||
|
||||
def _compute_balance_end_real(self, cr, uid, journal_id, context=None):
|
||||
|
||||
cr.execute('SELECT balance_end_real \
|
||||
FROM account_bank_statement \
|
||||
WHERE journal_id = %s AND NOT state = %s \
|
||||
ORDER BY date DESC,id DESC LIMIT 1', (journal_id, 'draft'))
|
||||
res = cr.fetchone()
|
||||
|
||||
print "res: %r" % (res,)
|
||||
|
||||
return res and res[0] or 0.0
|
||||
|
||||
def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
|
||||
|
|
|
@ -61,8 +61,8 @@ class account_cashbox_line(osv.osv):
|
|||
'pieces': fields.float('Unit of Currency', digits_compute=dp.get_precision('Account')),
|
||||
'number_opening' : fields.integer('Number of Units', help='Opening Unit Numbers'),
|
||||
'number_closing' : fields.integer('Number of Units', help='Closing Unit Numbers'),
|
||||
'subtotal_opening': fields.function(_sub_total, string='Subtotal Opening', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
|
||||
'subtotal_closing': fields.function(_sub_total, string='Subtotal Closing', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
|
||||
'subtotal_opening': fields.function(_sub_total, string='Opening Subtotal', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
|
||||
'subtotal_closing': fields.function(_sub_total, string='Closing Subtotal', type='float', digits_compute=dp.get_precision('Account'), multi='subtotal'),
|
||||
'bank_statement_id' : fields.many2one('account.bank.statement', ondelete='cascade'),
|
||||
}
|
||||
|
||||
|
@ -72,36 +72,24 @@ class account_cash_statement(osv.osv):
|
|||
|
||||
_inherit = 'account.bank.statement'
|
||||
|
||||
def _get_starting_balance(self, cr, uid, ids, context=None):
|
||||
|
||||
""" Find starting balance
|
||||
@param name: Names of fields.
|
||||
@param arg: User defined arguments
|
||||
@return: Dictionary of values.
|
||||
def _update_balances(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
Set starting and ending balances according to pieces count
|
||||
"""
|
||||
res = {}
|
||||
for statement in self.browse(cr, uid, ids, context=context):
|
||||
if statement.journal_id.type not in('cash'):
|
||||
if statement.journal_id.type not in ('cash',):
|
||||
continue
|
||||
res[statement.id] = {
|
||||
'balance_start': sum((line.pieces * line.number_opening
|
||||
for line in statement.details_ids), 0.0)
|
||||
start = end = 0
|
||||
for line in statement.details_ids:
|
||||
start += line.subtotal_opening
|
||||
end += line.subtotal_closing
|
||||
data = {
|
||||
'balance_start': start,
|
||||
'balance_end_real': end,
|
||||
}
|
||||
|
||||
print "_get_starting_balance: %r" % (res,)
|
||||
return res
|
||||
|
||||
def _balance_end_cash(self, cr, uid, ids, name, arg, context=None):
|
||||
""" Find ending balance "
|
||||
@param name: Names of fields.
|
||||
@param arg: User defined arguments
|
||||
@return: Dictionary of values.
|
||||
"""
|
||||
res = {}
|
||||
for statement in self.browse(cr, uid, ids, context=context):
|
||||
res[statement.id] = sum((line.pieces * line.number_closing
|
||||
for line in statement.details_ids), 0.0)
|
||||
print "_balance_end_cash: %r" % (res,)
|
||||
res[statement.id] = data
|
||||
super(account_cash_statement, self).write(cr, uid, [statement.id], data, context=context)
|
||||
return res
|
||||
|
||||
def _get_sum_entry_encoding(self, cr, uid, ids, name, arg, context=None):
|
||||
|
@ -114,7 +102,6 @@ class account_cash_statement(osv.osv):
|
|||
res = {}
|
||||
for statement in self.browse(cr, uid, ids, context=context):
|
||||
res[statement.id] = sum((line.amount for line in statement.line_ids), 0.0)
|
||||
print "_get_sum_entry_encoding: %r" % (res,)
|
||||
return res
|
||||
|
||||
def _get_company(self, cr, uid, context=None):
|
||||
|
@ -126,63 +113,7 @@ class account_cash_statement(osv.osv):
|
|||
company_id = company_pool.search(cr, uid, [])
|
||||
return company_id and company_id[0] or False
|
||||
|
||||
def _get_cash_open_box_lines(self, cr, uid, context=None):
|
||||
res = []
|
||||
curr = [1, 2, 5, 10, 20, 50, 100, 500]
|
||||
for rs in curr:
|
||||
dct = {
|
||||
'pieces': rs,
|
||||
'number': 0
|
||||
}
|
||||
res.append(dct)
|
||||
journal_ids = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash')], context=context)
|
||||
if journal_ids:
|
||||
results = self.search(cr, uid, [('journal_id', 'in', journal_ids),('state', '=', 'confirm')], context=context)
|
||||
if results:
|
||||
cash_st = self.browse(cr, uid, results, context=context)[0]
|
||||
for cash_line in cash_st.ending_details_ids:
|
||||
for r in res:
|
||||
if cash_line.pieces == r['pieces']:
|
||||
r['number'] = cash_line.number
|
||||
return res
|
||||
|
||||
def _get_default_cash_close_box_lines(self, cr, uid, context=None):
|
||||
res = []
|
||||
curr = [1, 2, 5, 10, 20, 50, 100, 500]
|
||||
for rs in curr:
|
||||
dct = {
|
||||
'pieces': rs,
|
||||
'number': 0
|
||||
}
|
||||
res.append(dct)
|
||||
return res
|
||||
|
||||
def _get_cash_close_box_lines(self, cr, uid, context=None):
|
||||
res = []
|
||||
curr = [1, 2, 5, 10, 20, 50, 100, 500]
|
||||
for rs in curr:
|
||||
dct = {
|
||||
'pieces': rs,
|
||||
'number': 0
|
||||
}
|
||||
res.append((0, 0, dct))
|
||||
return res
|
||||
|
||||
def _get_cash_open_close_box_lines(self, cr, uid, context=None):
|
||||
res = {}
|
||||
start_l = []
|
||||
end_l = []
|
||||
starting_details = self._get_cash_open_box_lines(cr, uid, context=context)
|
||||
ending_details = self._get_default_cash_close_box_lines(cr, uid, context)
|
||||
for start in starting_details:
|
||||
start_l.append((0, 0, start))
|
||||
for end in ending_details:
|
||||
end_l.append((0, 0, end))
|
||||
res['start'] = start_l
|
||||
res['end'] = end_l
|
||||
return res
|
||||
|
||||
def _get_statement(self, cr, uid, ids, context=None):
|
||||
def _get_statement_from_line(self, cr, uid, ids, context=None):
|
||||
result = {}
|
||||
for line in self.pool.get('account.bank.statement.line').browse(cr, uid, ids, context=context):
|
||||
result[line.statement_id.id] = True
|
||||
|
@ -192,81 +123,46 @@ class account_cash_statement(osv.osv):
|
|||
result = dict.fromkeys(ids, 0.0)
|
||||
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
result[obj.id] = obj.balance_end - obj.balance_end_cash
|
||||
result[obj.id] = obj.balance_end_real - obj.balance_end
|
||||
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Cash Transaction", help="Total cash transactions",
|
||||
'total_entry_encoding': fields.function(_get_sum_entry_encoding, string="Total Cash Transactions",
|
||||
store = {
|
||||
'account.bank.statement': (lambda self, cr, uid, ids, context=None: ids, ['line_ids','move_line_ids'], 10),
|
||||
'account.bank.statement.line': (_get_statement, ['amount'], 10),
|
||||
'account.bank.statement.line': (_get_statement_from_line, ['amount'], 10),
|
||||
}),
|
||||
'closing_date': fields.datetime("Closed On"),
|
||||
'balance_end_cash': fields.function(_balance_end_cash, store=False, string='Closing Balance', help="Closing balance based on cashBox"),
|
||||
'details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='CashBox Lines'),
|
||||
'opening_details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='Opening Cashbox Lines'),
|
||||
'closing_details_ids' : fields.one2many('account.cashbox.line', 'bank_statement_id', string='Closing Cashbox Lines'),
|
||||
'user_id': fields.many2one('res.users', 'Responsible', required=False),
|
||||
'difference' : fields.function(_compute_difference, method=True, string="Difference", type="float"),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'state': 'draft',
|
||||
'date': lambda self, cr, uid, context={}: context.get('date', time.strftime("%Y-%m-%d %H:%M:%S")),
|
||||
'user_id': lambda self, cr, uid, context=None: uid,
|
||||
}
|
||||
|
||||
def check_opening_journal(self, cr, uid, ids, context=None):
|
||||
"""
|
||||
This constraint will check than the journal is not used twice in the system,
|
||||
to avoid a concurrency opening of this journal.
|
||||
"""
|
||||
for cash in self.browse(cr, uid, ids, context=None):
|
||||
domain = [
|
||||
('id', '!=', cash.id),
|
||||
('journal_id', '=', cash.journal_id.id),
|
||||
('journal_id.type', '=', 'cash'),
|
||||
('state', 'in', ('open',)),
|
||||
]
|
||||
count = self.search_count(cr, uid, domain, context=context)
|
||||
|
||||
if count:
|
||||
return False
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
#(check_opening_journal, "The selected journal has been opened !", ['journal_id']),
|
||||
]
|
||||
|
||||
def create(self, cr, uid, vals, context=None):
|
||||
if self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context).type == 'cash':
|
||||
amount_total = 0.0
|
||||
for line in vals.get('details_ids',[]):
|
||||
print "line: %r" % (line,)
|
||||
if line and len(line)==3 and line[2]:
|
||||
# FIXME: If there is no piece # does not work with GTK
|
||||
amount_total+= line[2].get('pieces', 0) * line[2]['number_opening']
|
||||
journal = False
|
||||
if vals.get('journal_id'):
|
||||
journal = self.pool.get('account.journal').browse(cr, uid, vals['journal_id'], context=context)
|
||||
if journal and (journal.type == 'cash') and not vals.get('details_ids'):
|
||||
vals['details_ids'] = []
|
||||
for value in journal.cashbox_line_ids:
|
||||
nested_values = {
|
||||
'number_closing' : 0,
|
||||
'number_opening' : 0,
|
||||
'pieces' : value.pieces
|
||||
}
|
||||
vals['details_ids'].append([0, False, nested_values])
|
||||
|
||||
vals.update(balance_start= amount_total)
|
||||
vals.update(balance_end_real=self._compute_balance_end_real(cr, uid, vals['journal_id'], context=context))
|
||||
|
||||
details = vals.get('details_ids')
|
||||
if not details:
|
||||
result = self.onchange_journal_id(cr, uid, None, vals['journal_id'], context=context)
|
||||
vals['details_ids'] = []
|
||||
|
||||
for value in (result['value']['details_ids'] or []):
|
||||
print "value: %r" % (value,)
|
||||
nested_values = {
|
||||
'number_closing' : False,
|
||||
'number_opening' : False,
|
||||
'pieces' : value['pieces'],
|
||||
'subtotal_closing' : False,
|
||||
'subtotal_opening' : False,
|
||||
}
|
||||
|
||||
vals['details_ids'].append([0, False, nested_values])
|
||||
|
||||
return super(account_cash_statement, self).create(cr, uid, vals, context=context)
|
||||
res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context)
|
||||
self._update_balances(cr, uid, [res_id], context)
|
||||
return res_id
|
||||
|
||||
def write(self, cr, uid, ids, vals, context=None):
|
||||
"""
|
||||
|
@ -282,58 +178,9 @@ class account_cash_statement(osv.osv):
|
|||
@return: True on success, False otherwise
|
||||
"""
|
||||
|
||||
super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
|
||||
res = self._get_starting_balance(cr, uid, ids)
|
||||
for rs in res:
|
||||
super(account_cash_statement, self).write(cr, uid, [rs], res.get(rs))
|
||||
return True
|
||||
|
||||
def onchange_journal_id(self, cr, uid, statement_id, journal_id, context=None):
|
||||
""" Changes balance start and starting details if journal_id changes"
|
||||
@param statement_id: Changed statement_id
|
||||
@param journal_id: Changed journal_id
|
||||
@return: Dictionary of changed values
|
||||
"""
|
||||
balance_start = 0.0
|
||||
if journal_id:
|
||||
count = self.search_count(cr, uid, [('journal_id', '=', journal_id),('state', '=', 'open')], context=None)
|
||||
if 0: # count:
|
||||
journal = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context)
|
||||
raise osv.except_osv(_('Error !'), (_('The Account Journal %s is opened by an other Cash Register !') % (journal.name,)))
|
||||
else:
|
||||
values = super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context)
|
||||
proxy_line = self.pool.get('account.cashbox.line')
|
||||
|
||||
values.setdefault('value', {})
|
||||
values['value']['details_ids'] = []
|
||||
values['value']['balance_end_real'] = self._compute_balance_end_real(cr, uid, journal_id, context=context)
|
||||
values['value']['balance_start'] = 0.0
|
||||
|
||||
journal = self.pool.get('account.journal').browse(cr, uid, journal_id, context=context)
|
||||
|
||||
for line in journal.cashbox_line_ids:
|
||||
values['value']['details_ids'].append({'pieces' : line.pieces})
|
||||
|
||||
return values
|
||||
else:
|
||||
return {
|
||||
'value' : {
|
||||
'balance_start': balance_start,
|
||||
'details_ids' : [],
|
||||
}
|
||||
}
|
||||
return super(account_cash_statement, self).onchange_journal_id(cr, uid, statement_id, journal_id, context=context)
|
||||
|
||||
def _equal_balance(self, cr, uid, cash_id, context=None):
|
||||
statement = self.browse(cr, uid, cash_id, context=context)
|
||||
self.write(cr, uid, [cash_id], {'balance_end_real': statement.balance_end})
|
||||
print "balance_end_real: %r" % (statement.balance_end,)
|
||||
print "balance_end: %r" % (statement.balance_end,)
|
||||
print "balance_end_cash: %r" % (statement.balance_end_cash,)
|
||||
|
||||
if statement.balance_end != statement.balance_end_cash:
|
||||
return False
|
||||
return True
|
||||
res = super(account_cash_statement, self).write(cr, uid, ids, vals, context=context)
|
||||
self._update_balances(cr, uid, ids, context)
|
||||
return res
|
||||
|
||||
def _user_allow(self, cr, uid, statement_id, context=None):
|
||||
return True
|
||||
|
@ -349,7 +196,7 @@ class account_cash_statement(osv.osv):
|
|||
for statement in statement_pool.browse(cr, uid, ids, context=context):
|
||||
vals = {}
|
||||
if not self._user_allow(cr, uid, statement.id, context=context):
|
||||
raise osv.except_osv(_('Error !'), (_('User %s does not have rights to access %s journal !') % (statement.user_id.name, statement.journal_id.name)))
|
||||
raise osv.except_osv(_('Error !'), (_('You do not have rights to open this %s journal !') % (statement.journal_id.name, )))
|
||||
|
||||
if statement.name and statement.name == '/':
|
||||
c = {'fiscalyear_id': statement.period_id.fiscalyear_id.id}
|
||||
|
@ -367,13 +214,6 @@ class account_cash_statement(osv.osv):
|
|||
self.write(cr, uid, [statement.id], vals, context=context)
|
||||
return True
|
||||
|
||||
def balance_check(self, cr, uid, cash_id, journal_type='bank', context=None):
|
||||
if journal_type == 'bank':
|
||||
return super(account_cash_statement, self).balance_check(cr, uid, cash_id, journal_type, context)
|
||||
if not self._equal_balance(cr, uid, cash_id, context):
|
||||
raise osv.except_osv(_('Error !'), _('The closing balance should be the same than the computed balance!'))
|
||||
return True
|
||||
|
||||
def statement_close(self, cr, uid, ids, journal_type='bank', context=None):
|
||||
if journal_type == 'bank':
|
||||
return super(account_cash_statement, self).statement_close(cr, uid, ids, journal_type, context)
|
||||
|
@ -419,14 +259,6 @@ class account_cash_statement(osv.osv):
|
|||
|
||||
return self.write(cr, uid, ids, {'closing_date': time.strftime("%Y-%m-%d %H:%M:%S")}, context=context)
|
||||
|
||||
def button_cancel(self, cr, uid, ids, context=None):
|
||||
cash_box_line_pool = self.pool.get('account.cashbox.line')
|
||||
super(account_cash_statement, self).button_cancel(cr, uid, ids, context=context)
|
||||
for st in self.browse(cr, uid, ids, context):
|
||||
for end in st.details_ids:
|
||||
cash_box_line_pool.write(cr, uid, [end.id], {'number_closing': 0})
|
||||
return True
|
||||
|
||||
account_cash_statement()
|
||||
|
||||
class account_journal(osv.osv):
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
</field>
|
||||
<separator colspan="4" string="States"/>
|
||||
<group>
|
||||
<field name="state" select="1" readonly="1"/>
|
||||
<field name="state" readonly="1"/>
|
||||
<button name="create_period" states="draft" string="Create Monthly Periods" type="object" icon="terp-document-new"/>
|
||||
<button name="create_period3" states="draft" string="Create 3 Months Periods" type="object" icon="terp-document-new"/>
|
||||
</group>
|
||||
|
@ -162,13 +162,13 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Account">
|
||||
<group col="6" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name="code" />
|
||||
<field name="company_id" widget="selection" groups="base.group_multi_company"/>
|
||||
<newline/>
|
||||
<field name="parent_id"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="user_type" select="1"/>
|
||||
<field name="type"/>
|
||||
<field name="user_type"/>
|
||||
<field name="active"/>
|
||||
<newline/>
|
||||
<field name="debit" invisible="context.get('config_invisible', True)" attrs="{'readonly':[('type','=','view')]}"/>
|
||||
|
@ -345,8 +345,8 @@
|
|||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Journal Column">
|
||||
<field colspan="4" name="name" select="1"/>
|
||||
<field name="field" select="1"/>
|
||||
<field colspan="4" name="name"/>
|
||||
<field name="field"/>
|
||||
<field name="sequence"/>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -455,8 +455,8 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Account Journal">
|
||||
<group colspan="4" col="6">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
<field name="type" on_change="onchange_type(type, currency, context)"/>
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
|
@ -487,6 +487,7 @@
|
|||
<separator string="Other Configuration" colspan="4"/>
|
||||
<field name="centralisation"/>
|
||||
<field name="entry_posted"/>
|
||||
<field name="with_last_closing_balance" />
|
||||
</group>
|
||||
<group colspan="2" col="2">
|
||||
<separator string="Invoicing Data" colspan="4"/>
|
||||
|
@ -504,18 +505,19 @@
|
|||
<separator colspan="4" string="Accounts Allowed (empty for no control)"/>
|
||||
<field colspan="4" name="account_control_ids" nolabel="1"/>
|
||||
</page>
|
||||
<page string="Cash Box">
|
||||
<page string="Cash">
|
||||
<separator string="Profit & Loss Accounts" colspan="4" />
|
||||
<field name="profit_account_id" />
|
||||
<field name="loss_account_id" />
|
||||
<separator string="Internal Account" colspan="4" />
|
||||
<field name="internal_account_id" />
|
||||
<separator string="Cash Box Lines" colspan="4" />
|
||||
|
||||
<separator string="Available Currencies" colspan="4" />
|
||||
<field name="cashbox_line_ids" nolabel="1" string="Unit Of Currency Definition" colspan="4">
|
||||
<tree string="CashBox Lines" editable="bottom">
|
||||
<field name="pieces" />
|
||||
</tree>
|
||||
</field>
|
||||
<label string="The Cashbox Lines will be used in the PoS Session" />
|
||||
</page>
|
||||
</notebook>
|
||||
</form>
|
||||
|
@ -607,9 +609,9 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Bank Statement">
|
||||
<group col="7" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="date" select="1" on_change="onchange_date(date, company_id)"/>
|
||||
<field name="journal_id" domain="[('type', '=', 'bank')]" on_change="onchange_journal_id(journal_id)" select="1" widget="selection"/>
|
||||
<field name="name"/>
|
||||
<field name="date" on_change="onchange_date(date, company_id)"/>
|
||||
<field name="journal_id" domain="[('type', '=', 'bank')]" on_change="onchange_journal_id(journal_id)" widget="selection"/>
|
||||
<newline/>
|
||||
<field name="period_id"/>
|
||||
<field name="balance_start"/>
|
||||
|
@ -668,8 +670,8 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Bank Statement">
|
||||
<group col="7" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="date" select="1" on_change="onchange_date(date, company_id)"/>
|
||||
<field name="name"/>
|
||||
<field name="date" on_change="onchange_date(date, company_id)"/>
|
||||
<field name='company_id' widget="selection" groups="base.group_multi_company" />
|
||||
<field name="journal_id" domain="[('type', '=', 'bank')]" on_change="onchange_journal_id(journal_id)" widget="selection"/>
|
||||
<newline/>
|
||||
|
@ -799,12 +801,12 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Account Type">
|
||||
<group col="6" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="code" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name="code"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Reporting Configuration" colspan="4"/>
|
||||
<field name="report_type" select="2"/>
|
||||
<field name="report_type"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Closing Method" colspan="4"/>
|
||||
|
@ -856,9 +858,9 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Journal Entry Reconcile">
|
||||
<group col="6" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="create_date" select="1"/>
|
||||
<field name="type" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name="create_date"/>
|
||||
<field name="type"/>
|
||||
</group>
|
||||
<separator colspan="4" string="Reconcile Entries"/>
|
||||
<field colspan="4" name="line_id" nolabel="1"/>
|
||||
|
@ -1094,9 +1096,9 @@
|
|||
<field name="arch" type="xml">
|
||||
<form string="Journal Item">
|
||||
<group col="6" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name="ref"/>
|
||||
<field name="partner_id" select="1" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
|
||||
|
||||
<field name="journal_id"/>
|
||||
<field name="period_id"/>
|
||||
|
@ -1106,7 +1108,7 @@
|
|||
<page string="Information">
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="Amount"/>
|
||||
<field name="account_id" select="1" domain="[('company_id', '=', company_id), ('type','<>','view'), ('type','<>','consolidation')]"/>
|
||||
<field name="account_id" domain="[('company_id', '=', company_id), ('type','<>','view'), ('type','<>','consolidation')]"/>
|
||||
<field name="debit"/>
|
||||
<field name="credit"/>
|
||||
<field name="quantity"/>
|
||||
|
@ -1121,7 +1123,7 @@
|
|||
|
||||
<group col="2" colspan="2">
|
||||
<separator colspan="2" string="Dates"/>
|
||||
<field name="date" select="1"/>
|
||||
<field name="date"/>
|
||||
<field name="date_maturity"/>
|
||||
<field name="date_created" readonly="True"/>
|
||||
</group>
|
||||
|
@ -1176,11 +1178,11 @@
|
|||
<notebook colspan="4">
|
||||
<page string="Information">
|
||||
<separator colspan="4" string="General Information"/>
|
||||
<field name="name" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name="date"/>
|
||||
<field name="journal_id" readonly="False" select="1"/>
|
||||
<field name="journal_id" readonly="False"/>
|
||||
<field name="period_id" readonly="False"/>
|
||||
<field name="account_id" select="1" domain="[('type','<>','view'),('type','<>','consolidation'),('company_id', '=', company_id)]"/>
|
||||
<field name="account_id" domain="[('type','<>','view'),('type','<>','consolidation'),('company_id', '=', company_id)]"/>
|
||||
<field name="partner_id" on_change="onchange_partner_id(False,partner_id,account_id,debit,credit,date)"/>
|
||||
<newline/>
|
||||
<field name="debit"/>
|
||||
|
@ -1189,13 +1191,13 @@
|
|||
<separator colspan="4" string="Optional Information"/>
|
||||
<field name="currency_id"/>
|
||||
<field name="amount_currency"/>
|
||||
<field name="quantity" select="3"/>
|
||||
<field name="quantity"/>
|
||||
<field name="move_id" required="False"/>
|
||||
<newline/>
|
||||
<field name="date_maturity"/>
|
||||
<field name="date_created"/>
|
||||
<field name="date_created"/>
|
||||
<field name="blocked" select="3"/>
|
||||
<field name="blocked"/>
|
||||
<newline/>
|
||||
<field name="account_tax_id" domain="[('parent_id','=',False)]"/>
|
||||
<field name="analytic_account_id" domain="[('parent_id','!=',False)]" groups="analytic.group_analytic_accounting"/>
|
||||
|
@ -2624,9 +2626,18 @@ action = pool.get('res.config').next(cr, uid, [], context)
|
|||
<field name="model">account.bank.statement</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Statement">
|
||||
<form string="Statement" layout="manual">
|
||||
<div class="oe_form_topbar">
|
||||
<button name="button_cancel" states="confirm,open" string="Cancel" icon="terp-gtk-stop" type="object"/>
|
||||
<button name="button_confirm_cash" states="open" string="Close CashBox" icon="terp-dialog-close" type="object"/>
|
||||
<button name="button_open" states="draft" string="Open CashBox" icon="gtk-go-forward" type="object"/>
|
||||
<div class="oe_right">
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,open,confirm" nolabel="1"/>
|
||||
</div>
|
||||
</div>
|
||||
<sheet layout="auto">
|
||||
<group col="6" colspan="4">
|
||||
<field name="name" select="1"/>
|
||||
<field name="name"/>
|
||||
<field name='company_id' widget="selection" groups="base.group_multi_company" />
|
||||
<field name="journal_id" on_change="onchange_journal_id(journal_id)" select="1" widget="selection" domain="[('type', '=', 'cash')]"/>
|
||||
<field name="user_id" select="1" readonly="1"/>
|
||||
|
@ -2663,15 +2674,22 @@ action = pool.get('res.config').next(cr, uid, [], context)
|
|||
</form>
|
||||
</field>
|
||||
</page>
|
||||
<page string="CashBox">
|
||||
<page string="Cash Control">
|
||||
<group col="2" expand="1">
|
||||
<field name="details_ids" nolabel="1" >
|
||||
<!--attrs="{'readonly' : [('state', '=', 'open')]}">-->
|
||||
<tree string="" editable="bottom">
|
||||
<field name="pieces" readonly="1" />
|
||||
<field name="number_opening" string="Opening Unit Numbers" on_change="on_change_sub_opening(pieces, number_opening, parent.balance_end)" attrs="{'readonly' : [('parent.state', '!=', 'open')]}" />
|
||||
<field name="opening_details_ids" nolabel="1" colspan="4" attrs="{'invisible' : [('state', '!=', 'draft')]}">
|
||||
<tree string="Opening Cashbox Lines" editable="bottom">
|
||||
<field name="pieces"/>
|
||||
<field name="number_opening" string="Opening Unit Numbers" on_change="on_change_sub_opening(pieces, number_opening, parent.balance_end)"/>
|
||||
<field name="subtotal_opening" string="Opening Subtotal"/>
|
||||
<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')]}"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="closing_details_ids" nolabel="1" colspan="4" attrs="{'invisible' : [('state', '=', 'draft')]}">
|
||||
<tree string="Closing Cashbox Lines" editable="bottom">
|
||||
<field name="pieces" readonly="1" />
|
||||
<field name="number_opening" string="Opening Unit Numbers" readonly="1" />
|
||||
<field name="subtotal_opening" string="Opening Subtotal" readonly="1" />
|
||||
|
||||
<field name="number_closing" string="Closing Unit Numbers" on_change="on_change_sub_closing(pieces, number_closing, parent.balance_end)"/>
|
||||
<field name="subtotal_closing" string="Closing Subtotal"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
@ -2682,30 +2700,23 @@ action = pool.get('res.config').next(cr, uid, [], context)
|
|||
</page>
|
||||
</notebook>
|
||||
<group col="6" colspan="4">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Dates" colspan="4"/>
|
||||
<field name="date" select="1" attrs="{'readonly':[('state','!=','draft')]}" on_change="onchange_date(date, company_id)" string="Started On" />
|
||||
<field name="closing_date" select="1" readonly="1"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Opening Balance" colspan="4"/>
|
||||
<field name="balance_end_real" readonly="1" string="Last Closing Balance"/>
|
||||
<field name="balance_start" readonly="1" string="Computed Amount"/>
|
||||
<field name="balance_start" readonly="1" string="Opening Cash Control"/>
|
||||
<field name="total_entry_encoding" />
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Closing Balance" colspan="4"/>
|
||||
<field name="balance_end"/>
|
||||
<field name="balance_end_cash"/>
|
||||
<field name="difference" />
|
||||
<field name="balance_end_real" readonly="1" string="Closing Cash Control"/>
|
||||
<field name="balance_end" string="Theorical Cash Closing"/>
|
||||
</group>
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Dates" colspan="4"/>
|
||||
<field name="date" readonly="1"/>
|
||||
<field name="closing_date" readonly="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<group col="8" colspan="4">
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,confirm" colspan="4"/>
|
||||
<button name="button_cancel" states="confirm,open" string="Cancel" icon="terp-gtk-stop" type="object"/>
|
||||
<button name="button_confirm_cash" states="open" string="Close CashBox" icon="terp-dialog-close" type="object"/>
|
||||
<button name="button_open" states="draft" string="Open CashBox" icon="gtk-go-forward" type="object"/>
|
||||
</group>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
|
|
@ -57,7 +57,6 @@
|
|||
- pieces: 500.0
|
||||
number: 2
|
||||
subtotal: 1000.0
|
||||
balance_end_cash: 1120.0
|
||||
|
||||
-
|
||||
I clicked on Close CashBox button to close the cashbox
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
from osv import osv, fields
|
||||
import decimal_precision as dp
|
||||
from tools.translate import _
|
||||
|
||||
class CashBox(osv.osv_memory):
|
||||
_register = False
|
||||
|
@ -29,7 +30,7 @@ class CashBox(osv.osv_memory):
|
|||
for record in records:
|
||||
if not record.journal_id.internal_account_id:
|
||||
raise osv.except_osv(_('Error !'),
|
||||
_('Please check that internal 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)
|
||||
|
||||
|
|
|
@ -42,9 +42,10 @@ class account_bank_statement(osv.osv):
|
|||
def button_confirm_bank(self, cr, uid, ids, context=None):
|
||||
super(account_bank_statement, self).button_confirm_bank(cr, uid, ids, context=context)
|
||||
for st in self.browse(cr, uid, ids, context=context):
|
||||
cr.execute("UPDATE account_bank_statement_line \
|
||||
SET state='confirm' WHERE id in %s ",
|
||||
(tuple([x.id for x in st.line_ids]),))
|
||||
if st.line_ids:
|
||||
cr.execute("UPDATE account_bank_statement_line \
|
||||
SET state='confirm' WHERE id in %s ",
|
||||
(tuple([x.id for x in st.line_ids]),))
|
||||
return True
|
||||
|
||||
def button_cancel(self, cr, uid, ids, context=None):
|
||||
|
|
|
@ -218,7 +218,7 @@
|
|||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="account.view_bank_statement_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/notebook/page[@name='statement_line_ids']/field[@name='line_ids']/tree/field[@name='amount']" position="after">
|
||||
<xpath expr="//notebook/page[@name='statement_line_ids']/field[@name='line_ids']/tree/field[@name='amount']" position="after">
|
||||
<field name="voucher_id" context="{'line_type': type, 'default_type': amount < 0 and 'payment' or 'receipt', 'type': amount < 0 and 'payment' or 'receipt', 'default_partner_id': partner_id, 'default_journal_id': parent.journal_id, 'default_amount': abs(amount), 'default_reference': ref, 'default_date': date, 'default_name': name}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
|
@ -230,7 +230,7 @@
|
|||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="account.view_bank_statement_form"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/notebook/page[@name='statement_line_ids']/field[@name='line_ids']/form/field[@name='sequence']" position="before">
|
||||
<xpath expr="//notebook/page[@name='statement_line_ids']/field[@name='line_ids']/form/field[@name='sequence']" position="before">
|
||||
<field name="voucher_id" context="{'line_type': type, 'default_type': amount < 0 and 'payment' or 'receipt', 'type': amount < 0 and 'payment' or 'receipt', 'default_partner_id': partner_id, 'default_journal_id': parent.journal_id, 'default_amount': abs(amount), 'default_reference': ref, 'default_date': date, 'default_name': name}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
|
@ -241,7 +241,7 @@
|
|||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="account.view_bank_statement_form2"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/notebook/page/field[@name='line_ids']/tree/field[@name='amount']" position="after">
|
||||
<xpath expr="//field[@name='line_ids']/tree/field[@name='amount']" position="after">
|
||||
<field name="voucher_id" context="{'line_type': type, 'default_type': amount < 0 and 'payment' or 'receipt', 'type': amount < 0 and 'payment' or 'receipt', 'default_partner_id': partner_id, 'default_journal_id': parent.journal_id, 'default_amount': abs(amount), 'default_reference': ref, 'default_date': date, 'default_name': name}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
|
@ -253,7 +253,7 @@
|
|||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="account.view_bank_statement_form2"/>
|
||||
<field name="arch" type="xml">
|
||||
<xpath expr="/form/notebook/page/field[@name='line_ids']/form/field[@name='amount']" position="after">
|
||||
<xpath expr="//field[@name='line_ids']/form/field[@name='amount']" position="after">
|
||||
<field name="voucher_id" context="{'line_type': type, 'default_type': amount < 0 and 'payment' or 'receipt', 'type': amount < 0 and 'payment' or 'receipt', 'default_partner_id': partner_id, 'default_journal_id': parent.journal_id, 'default_amount': abs(amount), 'default_reference': ref, 'default_date': date, 'default_name': name}"/>
|
||||
</xpath>
|
||||
</field>
|
||||
|
|
|
@ -21,7 +21,6 @@
|
|||
|
||||
import point_of_sale
|
||||
import account_bank_statement
|
||||
import product
|
||||
import res_users
|
||||
import wizard
|
||||
import report
|
||||
|
|
|
@ -58,15 +58,14 @@ Main features :
|
|||
'wizard/pos_payment_report.xml',
|
||||
'wizard/pos_payment.xml',
|
||||
'wizard/pos_box.xml',
|
||||
'wizard/pos_session_opening.xml',
|
||||
'point_of_sale_report.xml',
|
||||
'point_of_sale_view.xml',
|
||||
'report/pos_order_report_view.xml',
|
||||
'report/report_cash_register_view.xml',
|
||||
'point_of_sale_sequence.xml',
|
||||
'point_of_sale_workflow.xml',
|
||||
'account_statement_view.xml',
|
||||
'account_statement_report.xml',
|
||||
'product_view.xml',
|
||||
'res_users_view.xml',
|
||||
],
|
||||
'demo_xml': [
|
||||
|
|
|
@ -30,6 +30,7 @@ class account_journal(osv.osv):
|
|||
'opening_control': fields.boolean('Opening Control', help="If you want the journal should be control at opening, check this option"),
|
||||
'closing_control': fields.boolean('Closing Control', help="If you want the journal should be control at closing, check this option"),
|
||||
|
||||
'amount_authorized_diff' : fields.float('Amount Authorized Difference'),
|
||||
}
|
||||
_defaults = {
|
||||
'opening_control' : True,
|
||||
|
@ -40,53 +41,9 @@ account_journal()
|
|||
|
||||
class account_cash_statement(osv.osv):
|
||||
_inherit = 'account.bank.statement'
|
||||
|
||||
#def _equal_balance(self, cr, uid, cash_id, context=None):
|
||||
# statement = self.browse(cr, uid, cash_id, context=context)
|
||||
# if not statement.journal_id.check_dtls:
|
||||
# return True
|
||||
# if statement.journal_id.check_dtls and (statement.balance_end != statement.balance_end_cash):
|
||||
# return False
|
||||
# else:
|
||||
# return True
|
||||
|
||||
def _get_cash_open_box_lines(self, cr, uid, context=None):
|
||||
res = super(account_cash_statement,self)._get_cash_open_box_lines(cr, uid, context)
|
||||
curr = [0.01, 0.02, 0.05, 0.10, 0.20, 0.50]
|
||||
for rs in curr:
|
||||
dct = {
|
||||
'pieces': rs,
|
||||
'number': 0
|
||||
}
|
||||
res.append(dct)
|
||||
res.sort()
|
||||
return res
|
||||
|
||||
def _get_default_cash_close_box_lines(self, cr, uid, context=None):
|
||||
res = super(account_cash_statement,self)._get_default_cash_close_box_lines(cr, uid, context=context)
|
||||
curr = [0.01, 0.02, 0.05, 0.10, 0.20, 0.50]
|
||||
for rs in curr:
|
||||
dct = {
|
||||
'pieces': rs,
|
||||
'number': 0
|
||||
}
|
||||
res.append(dct)
|
||||
res.sort()
|
||||
return res
|
||||
|
||||
def search(self, cr, uid, domain, offset=0, limit=None, order=None, context=None, count=False):
|
||||
if not context:
|
||||
context = {}
|
||||
pos_session_id = context.pop('pos_session_id', False) or False
|
||||
if pos_session_id and isinstance(pos_session_id, (int, long)):
|
||||
session = self.pool.get('pos.session').browse(cr, uid, pos_session_id, context=context)
|
||||
return [
|
||||
statement.id
|
||||
for order in session.order_ids
|
||||
for statement in order.statement_ids
|
||||
]
|
||||
return super(account_cash_statement, self).search(cr, uid, domain, offset=offset, limit=limit, order=order, context=context, count=count)
|
||||
|
||||
_columns = {
|
||||
'pos_session_id' : fields.many2one('pos.session'),
|
||||
}
|
||||
account_cash_statement()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -9,11 +9,11 @@
|
|||
<field name="arch" type="xml">
|
||||
<xpath expr="//notebook[last()]" position="inside">
|
||||
<page string="Point of Sale">
|
||||
<group col="6" colspan="4">
|
||||
<separator colspan="6" string="Extended Configuration"/>
|
||||
<group col="4" colspan="4">
|
||||
<field name="journal_user"/>
|
||||
<field name="opening_control" />
|
||||
<field name="closing_control" />
|
||||
<field name="opening_control"/>
|
||||
<field name="closing_control"/>
|
||||
<field name="amount_authorized_diff"/>
|
||||
</group>
|
||||
</page>
|
||||
</xpath>
|
||||
|
@ -129,6 +129,7 @@
|
|||
<field name="act_window_id" ref="action_new_bank_statement_all_tree"/>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
<menuitem name="Cash Register Management" parent="point_of_sale.menu_point_root"
|
||||
id="menu_point_open_config" sequence="10"/>
|
||||
<menuitem
|
||||
|
@ -156,6 +157,7 @@
|
|||
id="menu_all_menu_all_register"
|
||||
sequence="4"
|
||||
/>
|
||||
-->
|
||||
|
||||
|
||||
</data>
|
||||
|
|
|
@ -37,87 +37,76 @@ class pos_config(osv.osv):
|
|||
_name = 'pos.config'
|
||||
|
||||
POS_CONFIG_STATE = [
|
||||
('draft', 'Draft'),
|
||||
('active', 'Active'),
|
||||
('inactive', 'Inactive'),
|
||||
('deprecated', 'Deprecated')
|
||||
]
|
||||
|
||||
_columns = {
|
||||
'name' : fields.char('Name', size=32,
|
||||
select=1,
|
||||
required=True,
|
||||
readonly=True,
|
||||
states={'draft' : [('readonly', False)]}
|
||||
),
|
||||
'journal_ids' : fields.many2many('account.journal',
|
||||
'pos_config_journal_rel',
|
||||
'pos_config_id',
|
||||
'journal_id',
|
||||
'Payment Methods',
|
||||
domain="[('journal_user', '=', True )]",
|
||||
readonly=True,
|
||||
states={'draft' : [('readonly', False)]}
|
||||
),
|
||||
'name' : fields.char('Point of Sale Name', size=32, select=1,
|
||||
required=True, help="An internal identification of the point of sale"),
|
||||
'journal_ids' : fields.many2many('account.journal', 'pos_config_journal_rel',
|
||||
'pos_config_id', 'journal_id', 'Available Payment Methods',
|
||||
domain="[('journal_user', '=', True )]",),
|
||||
'shop_id' : fields.many2one('sale.shop', 'Shop',
|
||||
required=True,
|
||||
select=1,
|
||||
readonly=True,
|
||||
states={'draft' : [('readonly', False)]}
|
||||
),
|
||||
'journal_id' : fields.many2one('account.journal', 'Journal',
|
||||
required=True,
|
||||
select=1,
|
||||
domain=[('type', '=', 'sale')],
|
||||
readonly=True,
|
||||
states={'draft' : [('readonly', False)]}
|
||||
),
|
||||
'iface_self_checkout' : fields.boolean('Self Checkout Mode'),
|
||||
'iface_websql' : fields.boolean('WebSQL (to store data)'),
|
||||
required=True),
|
||||
'journal_id' : fields.many2one('account.journal', 'Sale Journal',
|
||||
required=True, domain=[('type', '=', 'sale')],
|
||||
help="Accounting journal used to post sales entries."),
|
||||
'iface_self_checkout' : fields.boolean('Self Checkout Mode',
|
||||
help="Check this if this point of sale should open by default in a self checkout mode. If unchecked, OpenERP uses the normal cashier mode by default."),
|
||||
'iface_websql' : fields.boolean('WebSQL (Faster but Chrome Only)',
|
||||
help="If have more than 200 products, it's highly suggested to use WebSQL "\
|
||||
"to store the data in the browser, instead of localStore mechanism. "\
|
||||
"It's more efficient but works on the Chrome browser only."
|
||||
),
|
||||
'iface_led' : fields.boolean('LED Interface'),
|
||||
'iface_cashdrawer' : fields.boolean('Cashdrawer Interface'),
|
||||
'iface_payment_terminal' : fields.boolean('Payment Terminal Interface'),
|
||||
'iface_electronic_scale' : fields.boolean('Electronic Scale Interface'),
|
||||
'iface_barscan' : fields.boolean('BarScan Interface'),
|
||||
'iface_vkeyboard' : fields.boolean('Virtual KeyBoard Interface'),
|
||||
'iface_print_via_proxy' : fields.boolean('Print via Proxy'),
|
||||
|
||||
'state' : fields.selection(POS_CONFIG_STATE, 'State',
|
||||
required=True,
|
||||
readonly=True),
|
||||
|
||||
'sequence_id' : fields.many2one('ir.sequence', 'Sequence',
|
||||
readonly=True),
|
||||
'user_id' : fields.many2one('res.users', 'User',
|
||||
readonly=True,
|
||||
states={'draft' : [('readonly', False)]}
|
||||
),
|
||||
'state' : fields.selection(POS_CONFIG_STATE, 'State', required=True, readonly=True),
|
||||
'sequence_id' : fields.many2one('ir.sequence', 'Order IDs Sequence', readonly=True,
|
||||
help="This sequence is automatically created by OpenERP but you can change it "\
|
||||
"to customize the reference numbers of your orders."),
|
||||
'session_ids': fields.one2many('pos.session', 'config_id', 'Sessions'),
|
||||
|
||||
}
|
||||
|
||||
def name_get(self, cr, uid, ids, context=None):
|
||||
result = []
|
||||
states = {
|
||||
'opening_control': _('Opening Control'),
|
||||
'opened': _('In Progress'),
|
||||
'closing_control': _('Closing Control'),
|
||||
'closed': _('Closed & Posted'),
|
||||
}
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
if (not record.session_ids) or (record.session_ids[0].state=='closed'):
|
||||
result.append((record.id, record.name+' ('+_('not used')+')'))
|
||||
continue
|
||||
session = record.session_ids[0]
|
||||
result.append((record.id, record.name + ' ('+session.user_id.name+', '+states[session.state]+')'))
|
||||
return result
|
||||
|
||||
|
||||
def _default_sale_journal(self, cr, uid, context=None):
|
||||
res = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'sale')], limit=1)
|
||||
return res and res[0] or False
|
||||
|
||||
def _default_shop(self, cr, uid, context=None):
|
||||
res = self.pool.get('sale.shop').search(cr, uid, [])
|
||||
return res and res[0] or False
|
||||
|
||||
_defaults = {
|
||||
'state' : 'draft',
|
||||
'user_id' : lambda obj, cr, uid, context: uid,
|
||||
'state' : POS_CONFIG_STATE[0][0],
|
||||
'shop_id': _default_shop,
|
||||
'journal_id': _default_sale_journal
|
||||
}
|
||||
|
||||
def _check_only_one_cash_journal(self, cr, uid, ids, context=None):
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
has_cash_journal = False
|
||||
|
||||
for journal in record.journal_ids:
|
||||
if journal.type == 'cash':
|
||||
if has_cash_journal:
|
||||
return False
|
||||
else:
|
||||
has_cash_journal = True
|
||||
return True
|
||||
|
||||
_constraints = [
|
||||
(_check_only_one_cash_journal, "You should have only one Cash Journal !", ['journal_id']),
|
||||
]
|
||||
|
||||
def set_draft(self, cr, uid, ids, context=None):
|
||||
return self.write(cr, uid, ids, {'state' : 'draft'}, context=context)
|
||||
|
||||
def set_active(self, cr, uid, ids, context=None):
|
||||
return self.write(cr, uid, ids, {'state' : 'active'}, context=context)
|
||||
|
||||
|
@ -128,173 +117,187 @@ class pos_config(osv.osv):
|
|||
return self.write(cr, uid, ids, {'state' : 'deprecated'}, context=context)
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
proxy = self.pool.get('ir.sequence.type')
|
||||
|
||||
sequence_values = dict(
|
||||
code='pos_%s_sequence' % values['name'].lower(),
|
||||
name='POS %s Sequence' % values['name'],
|
||||
)
|
||||
|
||||
proxy.create(cr, uid, sequence_values, context=context)
|
||||
|
||||
proxy = self.pool.get('ir.sequence')
|
||||
|
||||
sequence_values = dict(
|
||||
code='pos_%s_sequence' % values['name'].lower(),
|
||||
name='POS %s Sequence' % values['name'],
|
||||
padding=4,
|
||||
prefix="%s/%%(year)s/%%(month)s/%%(day)s/" % values['name'],
|
||||
name='PoS %s' % values['name'],
|
||||
padding=5,
|
||||
prefix="%s/" % values['name'],
|
||||
)
|
||||
sequence_id = proxy.create(cr, uid, sequence_values, context=context)
|
||||
|
||||
values['sequence_id'] = sequence_id
|
||||
return super(pos_config, self).create(cr, uid, values, context=context)
|
||||
|
||||
def write(self, cr, uid, ids, values, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.sequence_id and values.get('name', False):
|
||||
prefixes = obj.sequence_id.prefix.split('/')
|
||||
if len(prefixes) >= 4 and prefixes[0] == obj.name:
|
||||
prefixes[0] = values['name']
|
||||
|
||||
sequence_values = dict(
|
||||
code='pos_%s_sequence' % values['name'].lower(),
|
||||
name='POS %s Sequence' % values['name'],
|
||||
prefix="/".join(prefixes),
|
||||
)
|
||||
obj.sequence_id.write(sequence_values)
|
||||
|
||||
return super(pos_config, self).write(cr, uid, ids, values, context=context)
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.sequence_id:
|
||||
obj.sequence_id.unlink()
|
||||
|
||||
return super(pos_config, self).unlink(cr, uid, ids, context=context)
|
||||
|
||||
pos_config()
|
||||
|
||||
class pos_session(osv.osv):
|
||||
_name = 'pos.session'
|
||||
_order = 'id desc'
|
||||
|
||||
#"status [BUTTON TEXT]" -> utiliser
|
||||
# "opening control (open) -> opened (cashbox control) -> closing control (close) -> closed & posted"
|
||||
POS_SESSION_STATE = [('new', 'New'),('opened', 'Opened'),('closed', 'Closed'),('posted', 'Posted')]
|
||||
#POS_SESSION_STATE = [
|
||||
# ('new', 'Opening Control'),
|
||||
# ('opened', 'Opened'),
|
||||
# ('closed', 'Closing Control'),
|
||||
# ('posted', 'Closed & Posted'),
|
||||
#]
|
||||
POS_SESSION_STATE = [
|
||||
('opening_control', 'Opening Control'), # Signal open
|
||||
('opened', 'In Progress'), # Signal closing
|
||||
('closing_control', 'Closing Control'), # Signal close
|
||||
('closed', 'Closed & Posted'),
|
||||
]
|
||||
|
||||
def _compute_cash_register_id(self, cr, uid, ids, fieldnames, args, context=None):
|
||||
result = dict.fromkeys(ids, False)
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
for st in record.statement_ids:
|
||||
if st.journal_id.type == 'cash':
|
||||
result[record.id] = st.id
|
||||
break
|
||||
return result
|
||||
|
||||
_columns = {
|
||||
'config_id' : fields.many2one('pos.config', 'PoS',
|
||||
'config_id' : fields.many2one('pos.config', 'Point of Sale',
|
||||
help="The physical point of sale you will use.",
|
||||
required=True,
|
||||
select=1,
|
||||
domain="[('state', '=', 'active')]",
|
||||
readonly=True,
|
||||
states={'draft' : [('readonly', False)]}
|
||||
# readonly=True,
|
||||
# states={'draft' : [('readonly', False)]}
|
||||
),
|
||||
|
||||
'name' : fields.char('Session Sequence', size=32,
|
||||
'name' : fields.char('Session ID', size=32,
|
||||
required=True,
|
||||
select=1,
|
||||
readonly=True,
|
||||
states={'draft' : [('readonly', False)]}
|
||||
# readonly=True,
|
||||
# states={'draft' : [('readonly', False)]}
|
||||
),
|
||||
'user_id' : fields.many2one('res.users', 'User',
|
||||
'user_id' : fields.many2one('res.users', 'Responsible',
|
||||
required=True,
|
||||
select=1,
|
||||
readonly=True,
|
||||
states={'draft' : [('readonly', False)]}
|
||||
# readonly=True,
|
||||
# states={'draft' : [('readonly', False)]}
|
||||
),
|
||||
'start_at' : fields.datetime('Opening Date'),
|
||||
'stop_at' : fields.datetime('Closing Date'),
|
||||
|
||||
'state' : fields.selection(POS_SESSION_STATE, 'State',
|
||||
required=True,
|
||||
readonly=True,
|
||||
select=1),
|
||||
required=True, readonly=True,
|
||||
select=1),
|
||||
|
||||
'cash_register_id' : fields.many2one('account.bank.statement', 'Bank Account Statement',
|
||||
ondelete='cascade'),
|
||||
'cash_register_id' : fields.function(_compute_cash_register_id, method=True,
|
||||
type='many2one', relation='account.bank.statement',
|
||||
string='Cash Register', store=True),
|
||||
|
||||
'opening_details_ids' : fields.related('cash_register_id', 'opening_details_ids',
|
||||
type='one2many', relation='account.cashbox.line',
|
||||
string='Opening Cash Control'),
|
||||
'details_ids' : fields.related('cash_register_id', 'details_ids',
|
||||
type='one2many', relation='account.cashbox.line',
|
||||
string='CashBox Lines'),
|
||||
type='one2many', relation='account.cashbox.line',
|
||||
string='Cash Control'),
|
||||
|
||||
'cash_register_balance_end_real' : fields.related('cash_register_id', 'balance_end_real',
|
||||
type='float',
|
||||
digits_compute=dp.get_precision('Account'),
|
||||
string="Ending Balance",
|
||||
help="Computed using the cash control lines",
|
||||
readonly=True),
|
||||
'cash_register_balance_start' : fields.related('cash_register_id', 'balance_start',
|
||||
type='float',
|
||||
digits_compute=dp.get_precision('Account'),
|
||||
string="Starting Balance",
|
||||
help="Computed using the cash control at the opening.",
|
||||
readonly=True),
|
||||
'cash_register_total_entry_encoding' : fields.related('cash_register_id', 'total_entry_encoding',
|
||||
string='Total Cash Transaction',
|
||||
readonly=True),
|
||||
'cash_register_balance_end' : fields.related('cash_register_id', 'balance_end',
|
||||
type='float',
|
||||
digits_compute=dp.get_precision('Account'),
|
||||
string="Computed Balance",
|
||||
help="Computed with the initial cash control and the sum of all payments.",
|
||||
readonly=True),
|
||||
'cash_register_difference' : fields.related('cash_register_id', 'difference',
|
||||
type='float',
|
||||
string='Difference',
|
||||
help="Difference between the counted cash control at the closing and the computed balance.",
|
||||
readonly=True),
|
||||
|
||||
'journal_ids' : fields.related('config_id', 'journal_ids',
|
||||
type='many2many',
|
||||
readonly=True,
|
||||
relation='account.journal',
|
||||
string='Journals'),
|
||||
string='Available Payment Methods'),
|
||||
'order_ids' : fields.one2many('pos.order', 'session_id', 'Orders'),
|
||||
|
||||
'statement_ids' : fields.one2many('account.bank.statement', 'pos_session_id', 'Bank Statement', readonly=True),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'name' : '/',
|
||||
'user_id' : lambda obj, cr, uid, context: uid,
|
||||
'state' : 'new',
|
||||
'state' : 'opening_control',
|
||||
}
|
||||
|
||||
_sql_constraints = [
|
||||
('uniq_name', 'unique(name)', "The name of this POS Session must be unique !"),
|
||||
]
|
||||
|
||||
def _create_cash_register(self, cr, uid, pos_config, user_id, context=None):
|
||||
if not pos_config:
|
||||
return False
|
||||
def _check_unicity(self, cr, uid, ids, context=None):
|
||||
for session in self.browse(cr, uid, ids, context=None):
|
||||
# open if there is no session in 'opening_control', 'opened', 'closing_control' for one user
|
||||
domain = [
|
||||
('state', '!=', 'closed'),
|
||||
('user_id', '=', uid)
|
||||
]
|
||||
count = self.search_count(cr, uid, domain, context=context)
|
||||
if count>1:
|
||||
return False
|
||||
return True
|
||||
|
||||
proxy = self.pool.get('account.bank.statement')
|
||||
def _check_pos_config(self, cr, uid, ids, context=None):
|
||||
for session in self.browse(cr, uid, ids, context=None):
|
||||
domain = [
|
||||
('state', '!=', 'closed'),
|
||||
('config_id', '=', session.config_id.id)
|
||||
]
|
||||
count = self.search_count(cr, uid, domain, context=context)
|
||||
if count>1:
|
||||
return False
|
||||
return True
|
||||
|
||||
journal_id = False
|
||||
for journal in pos_config.journal_ids:
|
||||
if journal.type == 'cash':
|
||||
journal_id = journal.id
|
||||
break
|
||||
|
||||
if not journal_id:
|
||||
return False
|
||||
|
||||
values = {
|
||||
'journal_id' : journal_id,
|
||||
'user_id' : pos_config.user_id and pos_config.user_id.id or uid,
|
||||
}
|
||||
cash_register_id = proxy.create(cr, uid, values, context=context)
|
||||
|
||||
return cash_register_id
|
||||
_constraints = [
|
||||
(_check_unicity, "You can not create two active sessions with the same responsible!", ['user_id', 'state']),
|
||||
(_check_pos_config, "You can not create two active sessions related to the same point of sale!", ['config_id']),
|
||||
]
|
||||
|
||||
def create(self, cr, uid, values, context=None):
|
||||
config_id = values.get('config_id', False) or False
|
||||
|
||||
pos_config = None
|
||||
if config_id:
|
||||
pos_config = self.pool.get('pos.config').browse(cr, uid, config_id, context=context)
|
||||
name = pos_config.sequence_id._next()
|
||||
user_id = values.get('user_id', uid) or uid
|
||||
values.update(
|
||||
name=name,
|
||||
cash_register_id=self._create_cash_register(cr, uid, pos_config, user_id=user_id, context=context),
|
||||
)
|
||||
else:
|
||||
raise osv.except_osv(_('Error!'), _('There is no POS Config attached to this POS Session'))
|
||||
|
||||
bank_statement_ids = []
|
||||
for journal in pos_config.journal_ids:
|
||||
bank_values = {
|
||||
'journal_id' : journal.id,
|
||||
'user_id' : uid,
|
||||
}
|
||||
statement_id = self.pool.get('account.bank.statement').create(cr, uid, bank_values, context=context)
|
||||
bank_statement_ids.append(statement_id)
|
||||
|
||||
values.update({
|
||||
'name' : pos_config.sequence_id._next(),
|
||||
'statement_ids' : [(6, 0, bank_statement_ids)]
|
||||
})
|
||||
|
||||
return super(pos_session, self).create(cr, uid, values, context=context)
|
||||
|
||||
def unlink(self, cr, uid, ids, context=None):
|
||||
for obj in self.browse(cr, uid, ids, context=context):
|
||||
if obj.cash_register_id:
|
||||
obj.cash_register_id.unlink(context=context)
|
||||
for statement in obj.statement_ids:
|
||||
statement.unlink(context=context)
|
||||
return True
|
||||
|
||||
def on_change_config(self, cr, uid, ids, config_id, context=None):
|
||||
result = dict(value=dict())
|
||||
if not config_id:
|
||||
result['value']['user_id'] = uid
|
||||
else:
|
||||
result['value']['user_id'] = self.pool.get('pos.config').browse(cr, uid, config_id, context=context).user_id.id
|
||||
|
||||
return result
|
||||
|
||||
def wkf_action_open(self, cr, uid, ids, context=None):
|
||||
# si pas de date start_at, je balance une date, sinon on utilise celle de l'utilisateur
|
||||
for record in self.browse(cr, uid, ids, context=context):
|
||||
|
@ -302,21 +305,62 @@ class pos_session(osv.osv):
|
|||
if not record.start_at:
|
||||
values['start_at'] = time.strftime('%Y-%m-%d %H:%M:%S')
|
||||
values['state'] = 'opened'
|
||||
|
||||
record.write(values, context=context)
|
||||
|
||||
record.cash_register_id.button_open(context=context)
|
||||
|
||||
for st in record.statement_ids:
|
||||
st.button_open(context=context)
|
||||
return True
|
||||
|
||||
def wkf_action_closing_control(self, cr, uid, ids, context=None):
|
||||
for session in self.browse(cr, uid, ids, context=context):
|
||||
for statement in session.statement_ids:
|
||||
if not statement.journal_id.closing_control:
|
||||
if statement.balance_end<>statement.balance_end_real:
|
||||
self.pool.get('account.bank.statement').write(cr, uid,
|
||||
[statement.id], {'balance_end_real': statement.balance_end})
|
||||
return self.write(cr, uid, ids, {'state' : 'closing_control', 'stop_at' : time.strftime('%Y-%m-%d %H:%M:%S')}, context=context)
|
||||
|
||||
def wkf_action_close(self, cr, uid, ids, context=None):
|
||||
# Close CashBox
|
||||
record.cash_register_id.button_confirm_cash(context=context)
|
||||
return self.write(cr, uid, ids, {'state' : 'close', 'stop_at' : time.strftime('%Y-%m-%d %H:%M:%S')}, context=context)
|
||||
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:
|
||||
# The pos manager can close statements with maximums.
|
||||
if not self.pool.get('ir.model.access').check_groups(cr, uid, "point_of_sale.group_pos_manager"):
|
||||
raise osv.except_osv( _('Error !'),
|
||||
_("Your ending balance is too different from the theorical cash closing (%.2f), the maximum allowed is: %.2f. You can contact your manager to force it.") % (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)
|
||||
|
||||
def wkf_action_post(self, cr, uid, ids, context=None):
|
||||
getattr(st, 'button_confirm_%s' % st.journal_id.type)(context=context)
|
||||
self._confirm_orders(cr, uid, ids, context=context)
|
||||
return self.write(cr, uid, ids, {'state' : 'post'}, context=context)
|
||||
return self.write(cr, uid, ids, {'state' : 'closed'}, context=context)
|
||||
|
||||
def has_opening_control(self, cr, uid, ids, context=None):
|
||||
return any(journal.opening_control == True
|
||||
for session in self.browse(cr, uid, ids, context=context)
|
||||
for journal in session.config_id.journal_ids)
|
||||
|
||||
def has_closing_control(self, cr, uid, ids, context=None):
|
||||
result = any(journal.closing_control == True
|
||||
for session in self.browse(cr, uid, ids, context=context)
|
||||
for journal in session.config_id.journal_ids)
|
||||
return result
|
||||
|
||||
def _confirm_orders(self, cr, uid, ids, context=None):
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
|
@ -355,7 +399,7 @@ class pos_session(osv.osv):
|
|||
|
||||
if not pos_config_ids:
|
||||
raise osv.except_osv(_('Error !'),
|
||||
_('There is no active PoS Config for this User %s') % current_user.name)
|
||||
_('There is no active Point of Sale Config for this User %s') % current_user.name)
|
||||
|
||||
config = pos_config_proxy.browse(cr, uid, pos_config_ids[0], context=context)
|
||||
|
||||
|
@ -369,25 +413,11 @@ class pos_session(osv.osv):
|
|||
|
||||
session_id = self.create(cr, uid, values, context=context)
|
||||
wkf_service = netsvc.LocalService('workflow')
|
||||
wkf_service.trg_validate(uid, 'pos.session', session_id, 'open', cr)
|
||||
|
||||
wkf_service.trg_validate(uid, 'pos.session', session_id, 'opening_control', cr)
|
||||
return session_id
|
||||
|
||||
pos_session()
|
||||
|
||||
class pos_config_journal(osv.osv):
|
||||
""" Point of Sale journal configuration"""
|
||||
_name = 'pos.config.journal'
|
||||
_description = "Journal Configuration"
|
||||
|
||||
_columns = {
|
||||
'name': fields.char('Description', size=64),
|
||||
'code': fields.char('Code', size=64),
|
||||
'journal_id': fields.many2one('account.journal', "Journal")
|
||||
}
|
||||
|
||||
pos_config_journal()
|
||||
|
||||
class pos_order(osv.osv):
|
||||
_name = "pos.order"
|
||||
_description = "Point of Sale"
|
||||
|
@ -453,14 +483,6 @@ class pos_order(osv.osv):
|
|||
res[order.id]['amount_total'] = cur_obj.round(cr, uid, cur, val1)
|
||||
return res
|
||||
|
||||
def _default_sale_journal(self, cr, uid, context=None):
|
||||
res = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'sale')], limit=1)
|
||||
return res and res[0] or False
|
||||
|
||||
def _default_shop(self, cr, uid, context=None):
|
||||
res = self.pool.get('sale.shop').search(cr, uid, [])
|
||||
return res and res[0] or False
|
||||
|
||||
def copy(self, cr, uid, id, default=None, context=None):
|
||||
if not default:
|
||||
default = {}
|
||||
|
@ -479,10 +501,9 @@ class pos_order(osv.osv):
|
|||
_columns = {
|
||||
'name': fields.char('Order Ref', size=64, required=True, readonly=True),
|
||||
'company_id':fields.many2one('res.company', 'Company', required=True, readonly=True),
|
||||
'shop_id': fields.many2one('sale.shop', 'Shop', required=True,
|
||||
states={'draft': [('readonly', False)]}, readonly=True),
|
||||
'date_order': fields.datetime('Date Ordered', readonly=True, select=True),
|
||||
'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."),
|
||||
'shop_id': fields.related('session_id', 'config_id', 'shop_id', relation='sale.shop', type='many2one', string='Shop', store=True, readonly=True),
|
||||
'date_order': fields.datetime('Order Date', readonly=True, select=True),
|
||||
'user_id': fields.many2one('res.users', 'Salesman', help="Person who uses the the cash register. It could be a reliever, a student or an interim employee."),
|
||||
'amount_tax': fields.function(_amount_all, string='Taxes', digits_compute=dp.get_precision('Point Of Sale'), multi='all'),
|
||||
'amount_total': fields.function(_amount_all, string='Total', multi='all'),
|
||||
'amount_paid': fields.function(_amount_all, string='Paid', states={'draft': [('readonly', False)]}, readonly=True, digits_compute=dp.get_precision('Point Of Sale'), multi='all'),
|
||||
|
@ -511,9 +532,15 @@ class pos_order(osv.osv):
|
|||
'picking_id': fields.many2one('stock.picking', 'Picking', readonly=True),
|
||||
'note': fields.text('Internal Notes'),
|
||||
'nb_print': fields.integer('Number of Print', readonly=True),
|
||||
'sale_journal': fields.many2one('account.journal', 'Journal', required=True, states={'draft': [('readonly', False)]}, readonly=True),
|
||||
|
||||
'sale_journal': fields.related('session_id', 'config_id', 'journal_id', relation='account.journal', type='many2one', string='Sale Journal', store=True, readonly=True),
|
||||
}
|
||||
|
||||
def _default_session(self, cr, uid, context=None):
|
||||
so = self.pool.get('pos.session')
|
||||
session_ids = so.search(cr, uid, [('state','=', 'opened'), ('user_id','=',uid)], context=context)
|
||||
return session_ids and session_ids[0] or False
|
||||
|
||||
def _default_pricelist(self, cr, uid, context=None):
|
||||
res = self.pool.get('sale.shop').search(cr, uid, [], context=context)
|
||||
if res:
|
||||
|
@ -527,9 +554,8 @@ class pos_order(osv.osv):
|
|||
'name': '/',
|
||||
'date_order': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'),
|
||||
'nb_print': 0,
|
||||
'session_id': _default_session,
|
||||
'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id,
|
||||
'sale_journal': _default_sale_journal,
|
||||
'shop_id': _default_shop,
|
||||
'pricelist_id': _default_pricelist,
|
||||
}
|
||||
|
||||
|
@ -600,18 +626,6 @@ class pos_order(osv.osv):
|
|||
picking_obj.force_assign(cr, uid, [picking_id], context)
|
||||
return True
|
||||
|
||||
def set_to_draft(self, cr, uid, ids, *args):
|
||||
if not len(ids):
|
||||
return False
|
||||
for order in self.browse(cr, uid, ids, context=context):
|
||||
if order.state != 'cancel':
|
||||
raise osv.except_osv(_('Error!'), _('In order to set to draft a sale, it must be cancelled.'))
|
||||
self.write(cr, uid, ids, {'state': 'draft'})
|
||||
wf_service = netsvc.LocalService("workflow")
|
||||
for i in ids:
|
||||
wf_service.trg_create(uid, 'pos.order', i, cr)
|
||||
return True
|
||||
|
||||
def cancel_order(self, cr, uid, ids, context=None):
|
||||
""" Changes order state to cancel
|
||||
@return: True
|
||||
|
@ -657,22 +671,29 @@ class pos_order(osv.osv):
|
|||
raise osv.except_osv(_('Configuration Error !'), msg)
|
||||
|
||||
context.pop('pos_session_id', False)
|
||||
domain = [
|
||||
('journal_id', '=', int(data['journal'])),
|
||||
('company_id', '=', curr_company),
|
||||
('user_id', '=', uid),
|
||||
('state', '=', 'open')
|
||||
]
|
||||
statement_id = statement_obj.search(cr,uid, domain, context=context)
|
||||
if len(statement_id) == 0:
|
||||
|
||||
try:
|
||||
journal_id = long(data['journal'])
|
||||
except Exception:
|
||||
journal_id = False
|
||||
|
||||
statement_id = False
|
||||
for statement in order.session_id.statement_ids:
|
||||
if statement.journal_id.id == journal_id:
|
||||
statement_id = statement.id
|
||||
break
|
||||
|
||||
if not statement_id:
|
||||
raise osv.except_osv(_('Error !'), _('You have to open at least one cashbox'))
|
||||
if statement_id:
|
||||
statement_id = statement_id[0]
|
||||
args['statement_id'] = statement_id
|
||||
args['pos_statement_id'] = order_id
|
||||
args['journal_id'] = int(data['journal'])
|
||||
args['type'] = 'customer'
|
||||
args['ref'] = order.name
|
||||
|
||||
args.update({
|
||||
'statement_id' : statement_id,
|
||||
'pos_statement_id' : order_id,
|
||||
'journal_id' : journal_id,
|
||||
'type' : 'customer',
|
||||
'ref' : order.name,
|
||||
})
|
||||
|
||||
statement_line_obj.create(cr, uid, args, context=context)
|
||||
ids_new.append(statement_id)
|
||||
|
||||
|
@ -896,7 +917,7 @@ class pos_order(osv.osv):
|
|||
continue
|
||||
|
||||
account_move_line_obj.create(cr, uid, {
|
||||
'name': "Tax" + line.name + " (%s)" % (tax.name),
|
||||
'name': _("Tax") + line.name + " (%s)" % (tax.name),
|
||||
'date': order.date_order[:10],
|
||||
'ref': order.name,
|
||||
'product_id':line.product_id.id,
|
||||
|
@ -935,7 +956,7 @@ class pos_order(osv.osv):
|
|||
|
||||
# counterpart
|
||||
to_reconcile.append(account_move_line_obj.create(cr, uid, {
|
||||
'name': "Trade Receivables", #order.name,
|
||||
'name': _("Trade Receivables"), #order.name,
|
||||
'date': order.date_order[:10],
|
||||
'ref': order.name,
|
||||
'move_id': move_id,
|
||||
|
@ -1073,7 +1094,7 @@ pos_order_line()
|
|||
|
||||
class pos_category(osv.osv):
|
||||
_name = 'pos.category'
|
||||
_description = "PoS Category"
|
||||
_description = "Point of Sale Category"
|
||||
_order = "sequence, name"
|
||||
def _check_recursion(self, cr, uid, ids, context=None):
|
||||
level = 100
|
||||
|
@ -1111,6 +1132,10 @@ class pos_category(osv.osv):
|
|||
'parent_id': fields.many2one('pos.category','Parent Category', select=True),
|
||||
'child_id': fields.one2many('pos.category', 'parent_id', string='Children Categories'),
|
||||
'sequence': fields.integer('Sequence', help="Gives the sequence order when displaying a list of product categories."),
|
||||
'to_weight' : fields.boolean('To Weight', help="This category contains products that should be weighted, mainly used for the self-checkout interface"),
|
||||
}
|
||||
_defaults = {
|
||||
'to_weight' : False,
|
||||
}
|
||||
pos_category()
|
||||
|
||||
|
@ -1134,9 +1159,9 @@ class product_product(osv.osv):
|
|||
return result
|
||||
|
||||
_columns = {
|
||||
'income_pdt': fields.boolean('PoS Cash Input', help="This is a product you can use to put cash into a statement for the point of sale backend."),
|
||||
'expense_pdt': fields.boolean('PoS Cash Output', help="This is a product you can use to take cash from a statement for the point of sale backend, exemple: money lost, transfer to bank, etc."),
|
||||
'pos_categ_id': fields.many2one('pos.category','PoS Category',
|
||||
'income_pdt': fields.boolean('Point of Sale Cash In', help="This is a product you can use to put cash into a statement for the point of sale backend."),
|
||||
'expense_pdt': fields.boolean('Point of Sale Cash Out', help="This is a product you can use to take cash from a statement for the point of sale backend, exemple: money lost, transfer to bank, etc."),
|
||||
'pos_categ_id': fields.many2one('pos.category','Point of Sale Category',
|
||||
help="If you want to sell this product through the point of sale, select the category it belongs to."),
|
||||
'product_image_small': fields.function(_get_small_image, string='Small Image', type="binary",
|
||||
store = {
|
||||
|
|
|
@ -16,16 +16,27 @@
|
|||
<field name="model">pos.order</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="PoS Orders">
|
||||
<group col="7" colspan="4">
|
||||
<field name="session_id" required="1" />
|
||||
<form string="Point of Sale Orders" layout="manual">
|
||||
<div class="oe_form_topbar">
|
||||
<button name="%(action_pos_payment)d" string="Payment" icon="gtk-apply" type="action" states="draft" context="{'pos_session_id' : session_id}"/>
|
||||
<button name="action_invoice" string="Invoice" icon="gtk-apply" type="object" states="paid" attrs="{'readonly': [('partner_id','=',False)]}"/>
|
||||
<button name="refund" string="Return Products" type="object" icon="gtk-ok"
|
||||
attrs="{'invisible':[('state','=','draft')]}"/>
|
||||
<button name="%(action_report_pos_receipt)d" string="Reprint" icon="gtk-print" type="action" states="paid,done,invoiced"/>
|
||||
<div class="oe_right">
|
||||
<field name="state" nolabel="1" widget="statusbar" statusbar_visible="draft,paid,done" statusbar_colors='{"cancel":"red"}'/>
|
||||
</div>
|
||||
</div>
|
||||
<sheet layout="auto">
|
||||
<group col="4" colspan="4">
|
||||
<field name="name"/>
|
||||
<field name="date_order"/>
|
||||
<field name="session_id" required="1" />
|
||||
<field name="partner_id" on_change="onchange_partner_id(partner_id)" context="{'search_default_customer':1}" attrs="{'readonly': [('state','=','invoiced')]}"/>
|
||||
<button name="action_invoice" string="Invoice" icon="gtk-apply" type="object" states="paid" attrs="{'readonly': [('partner_id','=',False)]}"/>
|
||||
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Sale Order">
|
||||
<page string="Products">
|
||||
<field name="lines" colspan="4" nolabel="1">
|
||||
<tree string="Order lines" editable="bottom">
|
||||
<field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,qty,parent.partner_id)"/>
|
||||
|
@ -52,16 +63,8 @@
|
|||
<button name="%(action_pos_discount)d" string="Discount" icon="gtk-remove" type="action" states="draft" />
|
||||
</group>
|
||||
|
||||
<separator colspan="4"/>
|
||||
<group colspan="4" col="8">
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,paid,done" statusbar_colors='{"cancel":"red"}'/>
|
||||
<button name="%(action_pos_payment)d" string="Payment" icon="gtk-apply" type="action" states="draft" context="{'pos_session_id' : session_id}"/>
|
||||
<button name="refund" string="Return Products" type="object" icon="gtk-ok"
|
||||
attrs="{'invisible':[('state','=','draft')]}"/>
|
||||
<button name="%(action_report_pos_receipt)d" string="Reprint" icon="gtk-print" type="action" states="paid,done,invoiced"/>
|
||||
</group>
|
||||
</page>
|
||||
<page string="Payment">
|
||||
<page string="Payments">
|
||||
<field name="statement_ids" colspan="4" nolabel="1">
|
||||
<tree editable="bottom" string="Statement lines">
|
||||
<field name="journal_id"/>
|
||||
|
@ -100,11 +103,12 @@
|
|||
<field colspan="4" name="note" nolabel="1"/>
|
||||
</page>
|
||||
</notebook>
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
<record model="ir.actions.act_window" id="action_pos_pos_form">
|
||||
<field name="name">PoS Orders</field>
|
||||
<field name="name">Orders</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">pos.order</field>
|
||||
<field name="view_type">form</field>
|
||||
|
@ -622,11 +626,13 @@
|
|||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<field name="company_id" position="after">
|
||||
<separator string="Point of Sale" colspan="2"/>
|
||||
<field name="income_pdt"/>
|
||||
<field name="expense_pdt"/>
|
||||
</field>
|
||||
<group name="misc" position="after">
|
||||
<group name="pos" colspan="2" col="2">
|
||||
<separator string="Point of Sale" colspan="2"/>
|
||||
<field name="income_pdt"/>
|
||||
<field name="expense_pdt"/>
|
||||
</group>
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
@ -636,11 +642,12 @@
|
|||
<field name="model">pos.category</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="PoS Categories">
|
||||
<form string="Product PoS Categories">
|
||||
<group colspan="4" col="6">
|
||||
<field name="name"/>
|
||||
<field name="parent_id"/>
|
||||
<field name="sequence"/>
|
||||
<field name="to_weight" />
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
|
@ -651,14 +658,14 @@
|
|||
<field name="type">tree</field>
|
||||
<field name="field_parent" eval="False"/>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="PoS Categories">
|
||||
<tree string="Product PoS Categories">
|
||||
<field name="sequence" invisible="1"/>
|
||||
<field name="complete_name"/>
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
<record id="pos_category_action" model="ir.actions.act_window">
|
||||
<field name="name">PoS Categories</field>
|
||||
<field name="name">Product Categories</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">pos.category</field>
|
||||
<field name="view_type">form</field>
|
||||
|
@ -676,7 +683,7 @@
|
|||
<field name="res_model">account.journal</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="context" eval="{'default_journal_user': 1, 'default_view_id': ref('account.account_journal_bank_view'), 'default_type': 'cash'}"/>
|
||||
<field name="context" eval="{'default_journal_user': 1, 'default_type': 'cash'}"/>
|
||||
<field name="domain">[('journal_user','=', 1)]</field>
|
||||
<field name="help">Payment methods are defined by accounting journals having the field Payment Method checked.</field>
|
||||
</record>
|
||||
|
@ -712,16 +719,6 @@
|
|||
<menuitem name="Point of Sale" parent="base.menu_reporting" id="menu_point_rep" sequence="50" groups="group_pos_manager"/>
|
||||
<!-- Invoice -->
|
||||
|
||||
<record model="ir.actions.act_window" id="action_pos_sale_all">
|
||||
<field name="name">All Sales Orders</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">pos.order</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="domain">[]</field>
|
||||
</record>
|
||||
<menuitem parent="menu_point_rep" id="menu_point_ofsale_all" action="action_pos_sale_all" sequence="1"/>
|
||||
|
||||
<record model="ir.actions.act_window" id="action_pos_invoice">
|
||||
<field name="name">Invoices</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
|
@ -731,10 +728,8 @@
|
|||
<field name="domain">[('origin','like','POS')]</field>
|
||||
</record>
|
||||
|
||||
<menuitem name="Reporting" id="menu_point_of_sale_reporting" parent="menu_point_root" sequence="20" />
|
||||
|
||||
<menuitem icon="STOCK_PRINT" action="action_report_pos_details"
|
||||
id="menu_pos_details" parent="menu_point_of_sale_reporting" sequence="6" />
|
||||
id="menu_pos_details" parent="menu_point_rep" sequence="6" />
|
||||
|
||||
<record model="ir.actions.client" id="action_pos_pos">
|
||||
<field name="name">Start Point of Sale</field>
|
||||
|
@ -756,48 +751,43 @@
|
|||
<field name="model">pos.config</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="PoS Configuration">
|
||||
<field name="name" />
|
||||
<notebook colspan="4">
|
||||
<page string="Payment Methods">
|
||||
<field name="journal_ids" colspan="4" nolabel="1">
|
||||
<tree string="Journals">
|
||||
<field name="code" />
|
||||
<field name="name" />
|
||||
<field name="type" />
|
||||
<field name="opening_control" />
|
||||
<field name="closing_control" />
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Accounting">
|
||||
<separator string="Accounting" colspan="4" />
|
||||
<field name="shop_id" widget="selection" />
|
||||
<field name="journal_id" widget="selection" />
|
||||
</page>
|
||||
<page string="Interfaces">
|
||||
<field name="iface_self_checkout" />
|
||||
<field name="iface_websql" />
|
||||
<field name="iface_led" />
|
||||
<field name="iface_cashdrawer" />
|
||||
<field name="iface_payment_terminal" />
|
||||
<field name="iface_electronic_scale" />
|
||||
<field name="iface_barscan" />
|
||||
<field name="iface_vkeyboard" />
|
||||
</page>
|
||||
<page string="Others">
|
||||
<field name="user_id" />
|
||||
<field name="sequence_id" />
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
<group colspan="4" col="6">
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,active,inactive,deprecated" statusbar_colors='{"active":"green", "deprecated" : "red"}'/>
|
||||
<button string="Set to Draft" name="set_draft" type="object" states="deprecated"/>
|
||||
<button string="Set to Active" name="set_active" type="object" states="draft,inactive"/>
|
||||
<form string="Point of Sale Configuration" layout="manual">
|
||||
<div class="oe_form_topbar">
|
||||
<button string="Set to Active" name="set_active" type="object" states="inactive,deprecated"/>
|
||||
<button string="Set to Inactive" name="set_inactive" type="object" states="active" />
|
||||
<button string="Set to Deprecated" name="set_deprecate" type="object" states="active,inactive" />
|
||||
</group>
|
||||
<div class="oe_right">
|
||||
<field name="state" widget="statusbar" statusbar_visible="active,inactive,deprecated" statusbar_colors='{"deprecated" : "red"}' nolabel="1"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<sheet layout="auto">
|
||||
<field name="name" placeholder="POS/0001"/>
|
||||
<field name="shop_id" widget="selection" />
|
||||
<field name="journal_id" widget="selection" />
|
||||
<field name="sequence_id" readonly="1"/>
|
||||
<separator string="Available Payment Methods" colspan="4"/>
|
||||
<field name="journal_ids" colspan="4" nolabel="1">
|
||||
<tree string="Journals">
|
||||
<field name="code" />
|
||||
<field name="name" />
|
||||
<field name="type" />
|
||||
<field name="opening_control" />
|
||||
<field name="closing_control" />
|
||||
</tree>
|
||||
</field>
|
||||
<separator string="Material Interfaces" colspan="4"/>
|
||||
<field name="iface_self_checkout" />
|
||||
<field name="iface_websql" />
|
||||
<field name="iface_led" />
|
||||
<field name="iface_cashdrawer" />
|
||||
<field name="iface_payment_terminal" />
|
||||
<field name="iface_electronic_scale" />
|
||||
<field name="iface_barscan" />
|
||||
<field name="iface_vkeyboard" />
|
||||
<field name="iface_print_via_proxy" />
|
||||
</sheet>
|
||||
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -807,10 +797,8 @@
|
|||
<field name="model">pos.config</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="PoS Configuration" colors="grey:state == 'inactive'">
|
||||
<tree string="Point of Sale Configuration" colors="grey:state == 'inactive'">
|
||||
<field name="name" />
|
||||
<field name="user_id" />
|
||||
<field name="journal_id" />
|
||||
<field name="shop_id" />
|
||||
<field name="state" />
|
||||
</tree>
|
||||
|
@ -822,21 +810,13 @@
|
|||
<field name="model">pos.config</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="PoS Config">
|
||||
<search string="Point of Sale Config">
|
||||
<filter string="Active" domain="[('state', '=', 'active')]" />
|
||||
<filter string="Inactive" domain="[('state', '=', 'inactive')]" />
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name" />
|
||||
<field name="user_id" />
|
||||
<field name="journal_id" />
|
||||
<field name="shop_id" />
|
||||
|
||||
<newline />
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by' : 'user_id'}" />
|
||||
<filter string="Journal" icon="terp-folder-orange" domain="[]" context="{'group_by' : 'journal_id'}" />
|
||||
<filter string="Shop" icon="terp-go-home" domain="[]" context="{'group_by' : 'shop_id'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -850,7 +830,7 @@
|
|||
domain="[('config_id', '=', active_id)]" />
|
||||
|
||||
<record model="ir.actions.act_window" id="action_pos_config_pos">
|
||||
<field name="name">PoS Config</field>
|
||||
<field name="name">Point of Sales</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">pos.config</field>
|
||||
<field name="view_type">form</field>
|
||||
|
@ -864,42 +844,95 @@
|
|||
id="menu_pos_config_pos"
|
||||
groups="group_pos_manager"/>
|
||||
|
||||
<act_window
|
||||
id="act_pos_session_orders"
|
||||
name="Orders"
|
||||
src_model="pos.session"
|
||||
res_model="pos.order"
|
||||
context="{'search_default_session_id': active_id, 'default_session_id' : active_id }" />
|
||||
|
||||
|
||||
|
||||
<record model="ir.ui.view" id="view_pos_session_form">
|
||||
<field name="name">pos.session.form.view</field>
|
||||
<field name="model">pos.session</field>
|
||||
<field name="type">form</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="PoS Session">
|
||||
<group colspan="4" col="6">
|
||||
<field name="config_id" on_change="on_change_config(config_id)" />
|
||||
<field name="name" />
|
||||
<form string="Point of Sale Session" layout="manual">
|
||||
<div class="oe_form_topbar">
|
||||
<button name="open" type="workflow" string="Validate & Open Session" states="opening_control" />
|
||||
<button name="cashbox_control" type="workflow" string="End of Session" states="opened" />
|
||||
<button name="close" type="workflow" string="Validate & 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="3">
|
||||
<button name="%(action_pos_box_in)d" string="Put Money In" type="action" states="opened"/>
|
||||
<button name="%(action_pos_box_out)d" string="Take Money Out" type="action" states="opened"/>
|
||||
<button name="%(act_pos_session_orders)d" string="Orders" type="action"/>
|
||||
</group>
|
||||
<newline/>
|
||||
<field name="user_id" />
|
||||
<field name="name" />
|
||||
<newline/>
|
||||
<field name="start_at" />
|
||||
<field name="stop_at" />
|
||||
</group>
|
||||
<notebook colspan="4">
|
||||
<page string="Cash">
|
||||
<field name="cash_register_id" invisible="0" />
|
||||
<field name="details_ids" colspan="4" nolabel="1">
|
||||
<tree string="" editable="bottom">
|
||||
<separator string="Cash Control" colspan="4"/>
|
||||
<field name="cash_register_id" invisible="1" />
|
||||
<field name="opening_details_ids" colspan="4" nolabel="1" attrs="{'invisible' : [('state', 'not in', ('opening_control',))]}">
|
||||
<tree string="Opening Cashbox Lines" editable="bottom">
|
||||
<field name="pieces" readonly="1" />
|
||||
<field name="number_opening" string="Opening Unit Numbers" on_change="on_change_sub_opening(pieces, number_opening, parent.balance_end)" />
|
||||
<field name="subtotal_opening" string="Opening Subtotal"/>
|
||||
<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"/>
|
||||
<field name="subtotal_opening" string="Opening Subtotal" sum="Total"/>
|
||||
</tree>
|
||||
</field>
|
||||
<field name="journal_ids" colspan="4" nolabel="1" />
|
||||
</page>
|
||||
</notebook>
|
||||
|
||||
<group colspan="4" col="5">
|
||||
<field name="state" widget="statusbar" statusbar_visible="new,opened,closed,posted" statusbar_colors='{"posted":"green"}'/>
|
||||
<button name="open" type="workflow" string="Open" states="new" />
|
||||
<button name="close" type="workflow" string="Close" states="opened" />
|
||||
<button name="post" type="workflow" string="Post" states="closed" />
|
||||
</group>
|
||||
<field name="details_ids" colspan="4" nolabel="1" attrs="{'invisible': [('state', '=', 'opening_control')]}">
|
||||
<tree string="Cashbox Lines" editable="bottom">
|
||||
<field name="pieces" readonly="1" />
|
||||
<field name="number_opening" readonly="1"/>
|
||||
<field name="subtotal_opening"/>
|
||||
<field name="number_closing"/>
|
||||
<field name="subtotal_closing"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
||||
|
||||
<group col="4" colspan="4">
|
||||
<group col="2" colspan="2">
|
||||
<separator string="Cash Balance" colspan="2"/>
|
||||
<field name="cash_register_balance_start" readonly="1" string="Opening Cash Control"/>
|
||||
<field name="cash_register_total_entry_encoding" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="+ Transactions"/>
|
||||
<field name="cash_register_balance_end" attrs="{'invisible' : [('state', '=', 'opening_control')]}" string="= Theorical Cash Closing"/>
|
||||
</group>
|
||||
<group col="2" colspan="2" attrs="{'invisible' : [('state', '=', 'opening_control')]}">
|
||||
<separator string="Cash Closing Balance" colspan="2"/>
|
||||
<field name="cash_register_balance_end_real"/>
|
||||
<field name="cash_register_difference" />
|
||||
</group>
|
||||
</group>
|
||||
<separator string="Summary by Payment Methods" colspan="4"/>
|
||||
<field name="statement_ids" colspan="4" nolabel="1">
|
||||
<tree string="Statements">
|
||||
<field name="name" />
|
||||
<field name="journal_id" />
|
||||
<field name="balance_start" />
|
||||
<field name="total_entry_encoding" />
|
||||
<field name="balance_end_real" />
|
||||
<field name="difference" />
|
||||
<field name="currency" />
|
||||
<field name="state" />
|
||||
</tree>
|
||||
</field>
|
||||
</group>
|
||||
|
||||
</sheet>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
@ -909,7 +942,7 @@
|
|||
<field name="model">pos.session</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="PoS Session">
|
||||
<tree string="Point of Sale Session">
|
||||
<field name="config_id" />
|
||||
<field name="name" />
|
||||
<field name="user_id" />
|
||||
|
@ -924,7 +957,7 @@
|
|||
<field name="model">pos.session</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="PoS Session">
|
||||
<search string="Point of Sale Session">
|
||||
<filter string="Open" domain="[('state', '=', 'opened')]" />
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Today" domain="[('start_at', '>=', time.strftime('%%Y-%%m-%%d 00:00:00'))]" />
|
||||
|
@ -936,7 +969,7 @@
|
|||
<newline />
|
||||
<group expand="0" string="Group By...">
|
||||
<filter string="User" icon="terp-personal" domain="[]" context="{'group_by' : 'user_id'}" />
|
||||
<filter string="PoS" domain="[]" context="{'group_by': 'user_id'}" />
|
||||
<filter string="Point of Sales" domain="[]" context="{'group_by': 'user_id'}" />
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
|
@ -944,7 +977,7 @@
|
|||
|
||||
|
||||
<record model="ir.actions.act_window" id="action_pos_session">
|
||||
<field name="name">PoS Sessions</field>
|
||||
<field name="name">All Sessions</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">pos.session</field>
|
||||
<field name="view_type">form</field>
|
||||
|
@ -953,26 +986,12 @@
|
|||
</record>
|
||||
|
||||
<menuitem
|
||||
parent="menu_point_of_sale"
|
||||
parent="menu_point_rep"
|
||||
action="action_pos_session"
|
||||
id="menu_pos_session"
|
||||
sequence="0"
|
||||
groups="group_pos_manager"/>
|
||||
|
||||
<act_window
|
||||
id="act_pos_session_orders"
|
||||
name="Orders"
|
||||
src_model="pos.session"
|
||||
res_model="pos.order"
|
||||
domain="[('session_id', '=', active_id)]" />
|
||||
|
||||
<act_window
|
||||
id="act_pos_session_statements"
|
||||
name="Statements"
|
||||
src_model="pos.session"
|
||||
res_model="account.bank.statement"
|
||||
domain="[]"
|
||||
context="{'pos_session_id' : active_id}" />
|
||||
|
||||
<record id="view_pos_order_filter" model="ir.ui.view">
|
||||
<field name="name">pos.order.list.select</field>
|
||||
<field name="model">pos.order</field>
|
||||
|
@ -985,15 +1004,15 @@
|
|||
<filter icon="terp-check" string="Invoiced" domain="[('state','=','invoiced')]"/>
|
||||
<filter icon="gtk-convert" string="Posted" domain="[('state','=','done')]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-month" string="Today" domain="[('date_order','>=',datetime.date.today().strftime('%%Y-%%m-%%d 00:00:00')),('date_order','<=',datetime.date.today().strftime('%%Y-%%m-%%d 23:59:59'))]"/>
|
||||
<filter icon="gtk-go-forward" string="Yesterday" domain="[('date_order','<',datetime.date.today().strftime('%%Y-%%m-%%d 00:00:00')),('date_order','>=',(datetime.date.today() - relativedelta(days=1)).strftime('%%Y-%%m-%%d 00:00:00'))]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="name"/>
|
||||
<field name="user_id"/>
|
||||
<field name="date_order"/>
|
||||
<field name="session_id"/>
|
||||
<newline/>
|
||||
<group expand="0" string="Group By..." groups="base.group_extended">
|
||||
<filter string="Customer" icon="terp-personal" domain="[]" context="{'group_by':'partner_id'}"/>
|
||||
<filter string="Salesman" icon="terp-personal" domain="[]" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Session" icon="terp-personal" domain="[]" context="{'group_by':'session_id'}"/>
|
||||
<separator string="" orientation="vertical"/>
|
||||
<filter string="State" icon="terp-stock_effects-object-colorize" domain="[]" context="{'group_by':'state'}"/>
|
||||
<separator string="" orientation="vertical"/>
|
||||
|
@ -1002,5 +1021,8 @@
|
|||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_pos_session_opening" parent="menu_point_of_sale" id="menu_pos_session_opening" />
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -86,51 +86,70 @@
|
|||
|
||||
<!-- Activities -->
|
||||
|
||||
<record model="workflow.activity" id="act_new">
|
||||
<record model="workflow.activity" id="act_opening_control">
|
||||
<field name="wkf_id" ref="wkf_pos_session"/>
|
||||
<field name="flow_start">True</field>
|
||||
<field name="name">new</field>
|
||||
<field name="name">opening_control</field>
|
||||
</record>
|
||||
|
||||
<record model="workflow.activity" id="act_open">
|
||||
<field name="wkf_id" ref="wkf_pos_session"/>
|
||||
<field name="name">open</field>
|
||||
<field name="name">opened</field>
|
||||
<field name="action">wkf_action_open()</field>
|
||||
<field name="kind">function</field>
|
||||
</record>
|
||||
|
||||
<record model="workflow.activity" id="act_closing_control">
|
||||
<field name="wkf_id" ref="wkf_pos_session"/>
|
||||
<field name="name">closing_control</field>
|
||||
<field name="action">wkf_action_closing_control()</field>
|
||||
<field name="kind">function</field>
|
||||
</record>
|
||||
|
||||
<record model="workflow.activity" id="act_close">
|
||||
<field name="wkf_id" ref="wkf_pos_session"/>
|
||||
<field name="name">close</field>
|
||||
<field name="flow_stop">True</field>
|
||||
<field name="name">closed</field>
|
||||
<field name="action">wkf_action_close()</field>
|
||||
<field name="kind">function</field>
|
||||
</record>
|
||||
|
||||
<record model="workflow.activity" id="act_post">
|
||||
<field name="wkf_id" ref="wkf_pos_session"/>
|
||||
<field name="flow_stop">True</field>
|
||||
<field name="name">post</field>
|
||||
<field name="action">wkf_action_post()</field>
|
||||
<field name="kind">function</field>
|
||||
</record>
|
||||
|
||||
<!-- Transitions -->
|
||||
<record model="workflow.transition" id="trans_new_open">
|
||||
<field name="act_from" ref="act_new"/>
|
||||
<field name="act_to" ref="act_open"/>
|
||||
<!-- state:opening_control -> signal:open -> state:opened -> signal:cashbox_control -> state:closing_control -> signal:close -> state:close -->
|
||||
|
||||
<record model="workflow.transition" id="trans_opening_control_to_open">
|
||||
<field name="act_from" ref="act_opening_control" />
|
||||
<field name="act_to" ref="act_open" />
|
||||
<field name="signal">open</field>
|
||||
</record>
|
||||
<!--
|
||||
<record model="workflow.transition" id="trans_opening_control_to_open_automatic">
|
||||
<field name="act_from" ref="act_opening_control" />
|
||||
<field name="act_to" ref="act_open" />
|
||||
<field name="signal" eval="False" />
|
||||
<field name="condition">not has_opening_control()</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
<record model="workflow.transition" id="trans_open_close">
|
||||
<field name="act_from" ref="act_open"/>
|
||||
<field name="act_to" ref="act_close"/>
|
||||
<field name="signal">close</field>
|
||||
<record model="workflow.transition" id="trans_open_to_closing_control">
|
||||
<field name="act_from" ref="act_open" />
|
||||
<field name="act_to" ref="act_closing_control" />
|
||||
<field name="signal">cashbox_control</field>
|
||||
</record>
|
||||
|
||||
<record model="workflow.transition" id="trans_close_post">
|
||||
<field name="act_from" ref="act_close"/>
|
||||
<field name="act_to" ref="act_post"/>
|
||||
<field name="signal">post</field>
|
||||
<!--
|
||||
<record model="workflow.transition" id="trans_closing_control_to_close_automatic">
|
||||
<field name="act_from" ref="act_closing_control" />
|
||||
<field name="act_to" ref="act_close" />
|
||||
<field name="signal" eval="False" />
|
||||
<field name="condition">not has_closing_control()</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
<record model="workflow.transition" id="trans_closing_control_to_close">
|
||||
<field name="act_from" ref="act_closing_control" />
|
||||
<field name="act_to" ref="act_close" />
|
||||
<field name="signal">close</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
from osv import osv, fields
|
||||
|
||||
class product_category(osv.osv):
|
||||
_inherit = 'product.category'
|
||||
|
||||
_columns = {
|
||||
'to_weight' : fields.boolean('To Weight'),
|
||||
}
|
||||
|
||||
_defaults = {
|
||||
'to_weight' : False,
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="product_category_form_view" model="ir.ui.view">
|
||||
<field name="name">product.category.form</field>
|
||||
<field name="model">product.category</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="product.product_category_form_view" />
|
||||
<field name="arch" type="xml">
|
||||
<field name="type" position="after">
|
||||
<field name="to_weight" />
|
||||
</field>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -33,6 +33,5 @@ import pos_sales_user_today
|
|||
import pos_payment_report_user
|
||||
import pos_report
|
||||
import pos_order_report
|
||||
import report_cash_register
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -69,13 +69,6 @@ class pos_details_summary(report_sxw.rml_parse):
|
|||
0.0 )
|
||||
|
||||
def _get_payments(self, objects):
|
||||
# gift_journal_id = None
|
||||
# if ignore_gift:
|
||||
# config_journal_ids = self.pool.get("pos.config.journal").search(self.cr, self.uid, [('code', '=', 'GIFT')])
|
||||
# if len(config_journal_ids):
|
||||
# config_journal = self.pool.get("pos.config.journal").browse(self.cr, self.uid, config_journal_ids, {})[0]
|
||||
# gift_journal_id = config_journal.journal_id.id
|
||||
|
||||
result = {}
|
||||
for obj in objects:
|
||||
for statement in obj.statement_ids:
|
||||
|
@ -136,4 +129,4 @@ report_sxw.report_sxw('report.pos.details_summary',
|
|||
parser=pos_details_summary,
|
||||
header='internal')
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -38,15 +38,6 @@
|
|||
<filter icon="terp-go-year" string="Year" name="year"
|
||||
domain="[('year','=',time.strftime('%%Y'))]"
|
||||
help="POS ordered created during current year"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-month" string="Month" name="This Month"
|
||||
domain="[('date','<=',(datetime.date.today()+relativedelta(day=31)).strftime('%%Y-%%m-%%d')),('date','>=',(datetime.date.today()-relativedelta(day=1)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="POS ordered created during current month"/>
|
||||
<filter icon="terp-go-month"
|
||||
string="Month -1"
|
||||
domain="[('date','<=', (datetime.date.today() - relativedelta(day=31, months=1)).strftime('%%Y-%%m-%%d')),('date','>=',(datetime.date.today() - relativedelta(day=1,months=1)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="POS ordered created last month"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-today"
|
||||
string="Today"
|
||||
name="today"
|
||||
|
@ -59,9 +50,10 @@
|
|||
<filter icon="terp-dolar"
|
||||
string="Not Invoiced"
|
||||
domain="[('state','=',('paid'))]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="user_id" widget="selection">
|
||||
<separator orientation="vertical"/>
|
||||
<field name="partner_id"/>
|
||||
<field name="date"/>
|
||||
<field name="user_id" widget="selection">
|
||||
<filter icon="terp-personal"
|
||||
string="My Sales"
|
||||
help="My Sales"
|
||||
|
@ -84,12 +76,12 @@
|
|||
</record>
|
||||
|
||||
<record id="action_report_pos_order_all" model="ir.actions.act_window">
|
||||
<field name="name">Point of Sale Analysis</field>
|
||||
<field name="name">Orders Analysis</field>
|
||||
<field name="res_model">report.pos.order</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree</field>
|
||||
<field name="search_view_id" ref="view_report_pos_order_search"/>
|
||||
<field name="context">{'search_default_year':1,'search_default_This Month':1,'search_default_today':1,'search_default_User':1,'group_by_no_leaf':1,'group_by':[]}</field>
|
||||
<field name="context">{'search_default_year':1,'search_default_today':1,'group_by_no_leaf':1,'group_by':['product_id']}</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_report_pos_order_all" id="menu_report_pos_order_all" parent="menu_point_rep" sequence="3"/>
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
##############################################################################
|
||||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
# published by the Free Software Foundation, either version 3 of the
|
||||
# License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Affero General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
import tools
|
||||
from osv import fields,osv
|
||||
|
||||
class report_cash_register(osv.osv):
|
||||
_name = "report.cash.register"
|
||||
_description = "Point of Sale Cash Register Analysis"
|
||||
_auto = False
|
||||
_columns = {
|
||||
'date': fields.date('Create Date', readonly=True),
|
||||
'year': fields.char('Year', size=4),
|
||||
'month':fields.selection([('01','January'), ('02','February'), ('03','March'), ('04','April'),
|
||||
('05','May'), ('06','June'), ('07','July'), ('08','August'), ('09','September'),
|
||||
('10','October'), ('11','November'), ('12','December')], 'Month',readonly=True),
|
||||
'day': fields.char('Day', size=128, readonly=True),
|
||||
'user_id':fields.many2one('res.users', 'User', readonly=True),
|
||||
'state': fields.selection([('draft', 'Quotation'),('open','Open'),('confirm', 'Confirmed')],'State'),
|
||||
'journal_id': fields.many2one('account.journal', 'Journal'),
|
||||
'balance_start': fields.float('Opening Balance'),
|
||||
'balance_end_real': fields.float('Closing Balance'),
|
||||
}
|
||||
_order = 'date desc'
|
||||
|
||||
def init(self, cr):
|
||||
tools.drop_view_if_exists(cr, 'report_cash_register')
|
||||
cr.execute("""
|
||||
create or replace view report_cash_register as (
|
||||
select
|
||||
min(s.id) as id,
|
||||
to_date(to_char(s.create_date, 'dd-MM-YYYY'),'dd-MM-YYYY') as date,
|
||||
s.user_id as user_id,
|
||||
s.journal_id as journal_id,
|
||||
s.state as state,
|
||||
s.balance_start as balance_start,
|
||||
s.balance_end_real as balance_end_real,
|
||||
to_char(s.create_date, 'YYYY') as year,
|
||||
to_char(s.create_date, 'MM') as month,
|
||||
to_char(s.create_date, 'YYYY-MM-DD') as day
|
||||
from account_bank_statement as s
|
||||
group by
|
||||
s.user_id,s.journal_id, s.balance_start, s.balance_end_real,s.state,to_char(s.create_date, 'dd-MM-YYYY'),
|
||||
to_char(s.create_date, 'YYYY'),
|
||||
to_char(s.create_date, 'MM'),
|
||||
to_char(s.create_date, 'YYYY-MM-DD'))""")
|
||||
|
||||
report_cash_register()
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
|
@ -1,89 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record id="view_report_cash_register_tree" model="ir.ui.view">
|
||||
<field name="name">report.cash.register.tree</field>
|
||||
<field name="model">report.cash.register</field>
|
||||
<field name="type">tree</field>
|
||||
<field name="arch" type="xml">
|
||||
<tree string="Point of Sale Cash Register Analysis">
|
||||
<field name="date" invisible="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="state" invisible="1"/>
|
||||
<field name="year" invisible="1"/>
|
||||
<field name="month" invisible="1"/>
|
||||
<field name="day" invisible="1"/>
|
||||
<field name="journal_id" invisible="1"/>
|
||||
<field name="balance_start" />
|
||||
<field name="balance_end_real" />
|
||||
</tree>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="view_report_cash_register_search" model="ir.ui.view">
|
||||
<field name="name">report.cash.register.search</field>
|
||||
<field name="model">report.cash.register</field>
|
||||
<field name="type">search</field>
|
||||
<field name="arch" type="xml">
|
||||
<search string="Point of Sale Cash Register Analysis">
|
||||
<group>
|
||||
<filter icon="terp-go-year" string="Year" name="year"
|
||||
domain="[('year','=',time.strftime('%%Y'))]"
|
||||
help="Cash Analysis created during this year"/>
|
||||
<separator orientation="vertical"/>
|
||||
|
||||
<filter icon="terp-go-month" string="Month" name="This Month"
|
||||
domain="[('date','<=',(datetime.date.today()+relativedelta(day=31)).strftime('%%Y-%%m-%%d')),('date','>=',(datetime.date.today()-relativedelta(day=1)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Cash Analysis created in current month"/>
|
||||
<filter icon="terp-go-month"
|
||||
string="Month -1"
|
||||
domain="[('date','<=', (datetime.date.today() - relativedelta(day=31, months=1)).strftime('%%Y-%%m-%%d')),('date','>=',(datetime.date.today() - relativedelta(day=1,months=1)).strftime('%%Y-%%m-%%d'))]"
|
||||
help="Cash Analysis created in last month"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-go-today"
|
||||
string=" Today "
|
||||
name="today"
|
||||
domain="[('date','=', time.strftime('%%Y-%%m-%%d'))]"
|
||||
help="Cash Analysis created by today"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter icon="terp-document-new"
|
||||
string="Draft"
|
||||
domain="[('state','=',('draft'))]"/>
|
||||
<filter icon="terp-camera_test"
|
||||
string="Confirm"
|
||||
domain="[('state','=',('confirm'))]"/>
|
||||
<separator orientation="vertical"/>
|
||||
<field name="user_id" widget="selection">
|
||||
<filter icon="terp-personal"
|
||||
string="My Sales"
|
||||
help="My Sales"
|
||||
domain="[('user_id','=',uid)]"/>
|
||||
</field>
|
||||
</group>
|
||||
<newline/>
|
||||
<group expand="1" string="Group By...">
|
||||
<filter string="User" name="User" icon="terp-personal" context="{'group_by':'user_id'}"/>
|
||||
<filter string="Journal" icon="terp-folder-orange" context="{'group_by':'journal_id'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="state" icon="terp-stock_effects-object-colorize" context="{'group_by':'state'}"/>
|
||||
<separator orientation="vertical"/>
|
||||
<filter string="Day" icon="terp-go-today" context="{'group_by':'day'}" help="Day from Creation date of cash register"/>
|
||||
<filter string="Month" icon="terp-go-month" context="{'group_by':'month'}" help="Month from Creation date of cash register"/>
|
||||
<filter string="Year" icon="terp-go-year" context="{'group_by':'year'}" help="Year from Creation date of cash register"/>
|
||||
</group>
|
||||
</search>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_report_cash_register_all" model="ir.actions.act_window">
|
||||
<field name="name">Register Analysis</field>
|
||||
<field name="res_model">report.cash.register</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">tree,form</field>
|
||||
<field name="search_view_id" ref="view_report_cash_register_search"/>
|
||||
<field name="context">{'search_default_year':1,'search_default_This Month':1,'search_default_today':1,'search_default_User':1,'group_by_no_leaf':1,'group_by':[]}</field>
|
||||
</record>
|
||||
|
||||
<menuitem action="action_report_cash_register_all" id="menu_report_cash_register_all" parent="menu_point_rep" sequence="1"/>
|
||||
</data>
|
||||
</openerp>
|
|
@ -36,19 +36,18 @@ def check_ean(eancode):
|
|||
|
||||
class res_users(osv.osv):
|
||||
_inherit = 'res.users'
|
||||
|
||||
_columns = {
|
||||
'ean13' : fields.char('EAN13', size=13, help="BarCode"),
|
||||
'pos_config' : fields.many2one('pos.config', 'Default Point of Sale', domain=[('state', '=', 'active')]),
|
||||
}
|
||||
|
||||
def _check_ean(self, cr, uid, ids, context=None):
|
||||
return all(
|
||||
check_ean(user.ean13) == True
|
||||
for user in self.browse(cr, uid, ids, context=context)
|
||||
)
|
||||
)
|
||||
|
||||
_constraints = [
|
||||
(_check_ean, "Error: Invalid ean code", ['ean13'],),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -1,18 +1,32 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<data>
|
||||
|
||||
<record id="res_users_form_preference_view" model="ir.ui.view">
|
||||
<field name="name">res.users.form.view</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="base.view_users_form_simple_modif" />
|
||||
<field name="arch" type="xml">
|
||||
<group name="preferences" position="inside">
|
||||
<field name="pos_config" />
|
||||
</group>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="res_users_form_view" model="ir.ui.view">
|
||||
<field name="name">res.users.form.view</field>
|
||||
<field name="model">res.users</field>
|
||||
<field name="type">form</field>
|
||||
<field name="inherit_id" ref="base.view_users_form" />
|
||||
<field name="arch" type="xml">
|
||||
<notebook position="inside">
|
||||
<page string="Point Of Sale">
|
||||
<field name="ean13" />
|
||||
</page>
|
||||
</notebook>
|
||||
<notebook position="inside">
|
||||
<page string="Point Of Sale">
|
||||
<field name="ean13" />
|
||||
<field name="pos_config" />
|
||||
</page>
|
||||
</notebook>
|
||||
</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_pos_config_journal,pos.config.journal,model_pos_config_journal,group_pos_user,1,0,0,0
|
||||
access_pos_order,pos.order,model_pos_order,group_pos_user,1,1,1,1
|
||||
access_pos_order_line,pos.order.line,model_pos_order_line,group_pos_user,1,1,1,1
|
||||
access_pos_order_manager,pos.order manager,model_pos_order,group_pos_manager,1,0,0,0
|
||||
access_pos_order_line_manager,pos.order.line manager,model_pos_order_line,group_pos_manager,1,0,0,0
|
||||
access_report_transaction_pos,report.transaction.pos,model_report_transaction_pos,group_pos_manager,1,1,1,1
|
||||
access_pos_config_journal_manager,pos.config.journal.manager,model_pos_config_journal,group_pos_manager,1,1,1,1
|
||||
access_account_journal_pos_user,account.journal pos_user,account.model_account_journal,group_pos_user,1,0,0,0
|
||||
access_account_move_pos_user,account.move pos_user,account.model_account_move,group_pos_user,1,1,1,0
|
||||
access_account_account_pos_user,account.account pos_user,account.model_account_account,group_pos_user,1,0,0,0
|
||||
|
@ -66,4 +64,4 @@ access_product_pricelist_manager,product.pricelist manager,product.model_product
|
|||
access_product_category_pos_manager,pos.category manager,model_pos_category,group_pos_manager,1,1,1,"1"""
|
||||
access_product_category_pos_user,pos.category user,model_pos_category,group_pos_user,1,0,0,"0"""
|
||||
access_pos_session_user,pos.session user,model_pos_session,group_pos_user,1,1,1,0
|
||||
access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,1,1,0
|
||||
access_pos_config_user,pos.config user,model_pos_config,group_pos_user,1,1,1,0
|
||||
|
|
|
|
@ -793,6 +793,10 @@ function openerp_pos_widgets(instance, module){ //module is instance.point_of_sa
|
|||
this.build_widgets();
|
||||
|
||||
instance.webclient.set_content_full_screen(true);
|
||||
if (self.pos.get('account_journals').length === 0) {
|
||||
// TODO: Create a popup to inform there is no PoSSession for this user
|
||||
self.pos.screen_selector.show_popup('error');
|
||||
}
|
||||
}, this));
|
||||
},
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import pos_receipt
|
|||
import pos_payment_report_user
|
||||
import pos_payment_report
|
||||
import pos_payment
|
||||
|
||||
import pos_session_opening
|
||||
import pos_box
|
||||
|
||||
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||
|
|
|
@ -69,7 +69,6 @@ class pos_box_entries(osv.osv_memory):
|
|||
|
||||
_columns = {
|
||||
'name': fields.char('Reason', size=32, required=True),
|
||||
#'journal_id': fields.selection(get_journal, "Cash Register", required=True, size=-1),
|
||||
'journal_id': fields.many2one('account.journal', 'Cash Register', required=True, domain="[('journal_id.type', '=', 'cash')]"),
|
||||
'product_id': fields.selection(_get_income_product, "Operation", required=True, size=-1),
|
||||
'amount': fields.float('Amount', digits=(16, 2), required=True),
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
<act_window name="Close Statements"
|
||||
res_model="pos.close.statement"
|
||||
src_model="account.bank.statement"
|
||||
|
@ -32,6 +33,7 @@
|
|||
target="new"
|
||||
key2="client_action_multi"
|
||||
id="act_pos_open_statement"/>
|
||||
-->
|
||||
|
||||
<record id="action_pos_close_statement" model="ir.actions.act_window">
|
||||
<field name="name">Close Cash Register</field>
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<!--
|
||||
<record id="action_pos_confirm" model="ir.actions.act_window">
|
||||
<field name="name">Post Sale Entries</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
|
@ -32,6 +32,7 @@
|
|||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
-->
|
||||
|
||||
</data>
|
||||
</openerp>
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
from osv import osv, fields
|
||||
from tools.translate import _
|
||||
import netsvc
|
||||
|
||||
class pos_session_opening(osv.osv_memory):
|
||||
_name = 'pos.session.opening'
|
||||
|
||||
_columns = {
|
||||
'pos_config_id' : fields.many2one('pos.config', 'Point of Sale', required=True),
|
||||
'pos_session_id' : fields.many2one('pos.session', 'PoS Session'),
|
||||
}
|
||||
|
||||
def open_session_cb(self, cr, uid, ids, context=None):
|
||||
assert len(ids) == 1, "you can open only one session at a time"
|
||||
proxy = self.pool.get('pos.session')
|
||||
wizard = self.browse(cr, uid, ids[0], context=context)
|
||||
if not wizard.pos_session_id:
|
||||
values = {
|
||||
'user_id' : uid,
|
||||
'config_id' : wizard.pos_config_id.id,
|
||||
}
|
||||
session_id = proxy.create(cr, uid, values, context=context)
|
||||
if all(journal.opening_control == False
|
||||
for journal in wizard.pos_config_id.journal_ids):
|
||||
|
||||
wkf_service = netsvc.LocalService('workflow')
|
||||
wkf_service.trg_validate(uid, 'pos.session', session_id, 'open', cr)
|
||||
return self._open_session(session_id)
|
||||
return self._open_session(wizard.pos_session_id.id)
|
||||
|
||||
def open_existing_session_cb(self, cr, uid, ids, context=None):
|
||||
assert len(ids) == 1
|
||||
wizard = self.browse(cr, uid, ids[0], context=context)
|
||||
return self._open_session(wizard.pos_session_id.id)
|
||||
|
||||
def _open_session(self, session_id):
|
||||
return {
|
||||
'name': _('Session'),
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form,tree',
|
||||
'res_model': 'pos.session',
|
||||
'res_id': session_id,
|
||||
'view_id': False,
|
||||
'type': 'ir.actions.act_window',
|
||||
}
|
||||
|
||||
def on_change_config(self, cr, uid, ids, config_id, context=None):
|
||||
if not config_id:
|
||||
return {}
|
||||
proxy = self.pool.get('pos.session')
|
||||
session_ids = proxy.search(cr, uid, [
|
||||
('state', '<>', 'closed'),
|
||||
('config_id', '=', config_id),
|
||||
], context=context)
|
||||
return {
|
||||
'value' : {
|
||||
'pos_session_id' : session_ids and session_ids[0] or False,
|
||||
}
|
||||
}
|
||||
|
||||
def default_get(self, cr, uid, fieldnames, context=None):
|
||||
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
|
||||
|
||||
return {
|
||||
'pos_config_id' : result,
|
||||
'pos_session_id': session_ids and session_ids[0] or False
|
||||
}
|
||||
pos_session_opening()
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<openerp>
|
||||
<data>
|
||||
<record model="ir.ui.view" id="pos_session_opening_form_view">
|
||||
<field name="name">pos.session.opening.form.view</field>
|
||||
<field name="model">pos.session.opening</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="PoS Session Opening" layout="auto">
|
||||
<separator string="Select your Point of Sale" colspan="4" />
|
||||
<field name="pos_config_id" on_change="on_change_config(pos_config_id)" widget="selection" domain="[('state','=','active')]"/>
|
||||
<field name="pos_session_id" invisible="1"/>
|
||||
<group colspan="4">
|
||||
<button special="cancel" icon="gtk-cancel" string="Cancel" />
|
||||
<button name="open_existing_session_cb" type="object" string="Open Session" icon="gtk-ok"
|
||||
attrs="{'invisible' : [('pos_session_id', '=', False)]}"
|
||||
/>
|
||||
<button name="open_session_cb" type="object" string="New Session" icon="gtk-ok"
|
||||
attrs="{'invisible' : [('pos_session_id', '<>', False)]}"
|
||||
/>
|
||||
</group>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_pos_session_opening" model="ir.actions.act_window">
|
||||
<field name="name">Open/Close a Session</field>
|
||||
<field name="type">ir.actions.act_window</field>
|
||||
<field name="res_model">pos.session.opening</field>
|
||||
<field name="view_type">form</field>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</data>
|
||||
</openerp>
|
|
@ -283,7 +283,7 @@
|
|||
<field name="inherit_id" ref="product.product_normal_form_view"/>
|
||||
<field name="arch" type="xml">
|
||||
<group name="misc" position="after">
|
||||
<group col="2" colspan="2" attrs="{'invisible':[('type', '=', 'service')]}">
|
||||
<group col="2" colspan="4" attrs="{'invisible':[('type', '=', 'service')]}">
|
||||
<separator string="Minimum Stock Rules" colspan="2"/>
|
||||
<field name="orderpoint_ids" context="{'default_product_uom': uom_id}" nolabel="1">
|
||||
<tree string="Minimum Stock Rule" editable="bottom">
|
||||
|
|
Loading…
Reference in New Issue