diff --git a/addons/account/account.py b/addons/account/account.py index 907e6207380..31fe7dbfb12 100644 --- a/addons/account/account.py +++ b/addons/account/account.py @@ -746,9 +746,11 @@ class account_journal(osv.osv): 'profit_account_id' : fields.many2one('account.account', 'Profit Account'), 'loss_account_id' : fields.many2one('account.account', 'Loss Account'), 'internal_account_id' : fields.many2one('account.account', 'Internal Transfers Account', select=1), + 'cash_control' : fields.boolean('Cash Control', help='If you want the journal should be control at opening/closing, check this option'), } _defaults = { + 'cash_control' : False, '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, diff --git a/addons/account/account_cash_statement.py b/addons/account/account_cash_statement.py index 9af0dcf60f4..17fa05d5f24 100644 --- a/addons/account/account_cash_statement.py +++ b/addons/account/account_cash_statement.py @@ -194,12 +194,27 @@ class account_cash_statement(osv.osv): 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'] = [] + + last_pieces = None + + if journal.with_last_closing_balance == True: + domain = [('journal_id', '=', journal.id), + ('state', '=', 'confirm')] + last_bank_statement_ids = self.search(cr, uid, domain, limit=1, order='create_date desc', context=context) + if last_bank_statement_ids: + last_bank_statement = self.browse(cr, uid, last_bank_statement_ids[0], context=context) + + last_pieces = dict( + (line.pieces, line.number_closing) for line in last_bank_statement.details_ids + ) + for value in journal.cashbox_line_ids: nested_values = { 'number_closing' : 0, - 'number_opening' : 0, + 'number_opening' : last_pieces.get(value.pieces, 0) if isinstance(last_pieces, dict) else 0, 'pieces' : value.pieces } + vals['details_ids'].append([0, False, nested_values]) res_id = super(account_cash_statement, self).create(cr, uid, vals, context=context) diff --git a/addons/account/account_view.xml b/addons/account/account_view.xml index 5bf45aab487..81e683e1cfd 100644 --- a/addons/account/account_view.xml +++ b/addons/account/account_view.xml @@ -515,7 +515,7 @@ - + @@ -524,10 +524,11 @@ + - - + + diff --git a/addons/account/demo/account_minimal.xml b/addons/account/demo/account_minimal.xml index baa94450f02..b7bc34a3e35 100644 --- a/addons/account/demo/account_minimal.xml +++ b/addons/account/demo/account_minimal.xml @@ -381,6 +381,11 @@ Cash Journal - (test) TCSH cash + + + + + diff --git a/addons/pad/pad.py b/addons/pad/pad.py index 6f6b435cf3c..d21ccd42d16 100644 --- a/addons/pad/pad.py +++ b/addons/pad/pad.py @@ -12,6 +12,8 @@ class pad_common(osv.osv_memory): def pad_generate_url(self, cr, uid, context=None): pad_server = self.pool.get('res.users').browse(cr, uid, uid, context).company_id.pad_server # make sure pad server in the form of http://hostname + if not pad_server: + return '' if not pad_server.startswith('http'): pad_server = 'http://' + pad_server pad_server = pad_server.rstrip('/') diff --git a/addons/point_of_sale/account_bank_statement.py b/addons/point_of_sale/account_bank_statement.py index eb7d791ebf9..06fe1d4a1f8 100644 --- a/addons/point_of_sale/account_bank_statement.py +++ b/addons/point_of_sale/account_bank_statement.py @@ -27,15 +27,10 @@ class account_journal(osv.osv): _columns = { 'journal_user': fields.boolean('PoS Payment Method', help="Check this box if this journal define a payment method that can be used in point of sales."), - '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'), 'self_checkout_payment_method' : fields.boolean('Self Checkout Payment Method'), } _defaults = { - 'opening_control' : False, - 'closing_control' : False, 'self_checkout_payment_method' : False, } @@ -46,6 +41,7 @@ class account_cash_statement(osv.osv): _columns = { 'pos_session_id' : fields.many2one('pos.session'), } + account_cash_statement() # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/account_statement_view.xml b/addons/point_of_sale/account_statement_view.xml index d7f3be2a8d6..86fc8fec164 100644 --- a/addons/point_of_sale/account_statement_view.xml +++ b/addons/point_of_sale/account_statement_view.xml @@ -10,8 +10,6 @@ - - @@ -113,37 +111,5 @@ - - - - diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index f4d32985688..b17e672cb9c 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -74,6 +74,26 @@ class pos_config(osv.osv): 'group_by' : fields.boolean('Group Journal Items', help="Check this if you want to group the Journal Items by Product while closing a Session"), } + def _check_cash_control(self, cr, uid, ids, context=None): + return all( + (sum(int(journal.cash_control) for journal in record.journal_ids) <= 1) + for record in self.browse(cr, uid, ids, context=context) + ) + + _constraints = [ + (_check_cash_control, "You cannot have two cash controls in one Point Of Sale !", ['journal_ids']), + ] + + def copy(self, cr, uid, id, default=None, context=None): + if not default: + default = {} + d = { + 'sequence_id' : False, + } + d.update(default) + return super(pos_order, self).copy(cr, uid, id, d, context=context) + + def name_get(self, cr, uid, ids, context=None): result = [] states = { @@ -90,11 +110,6 @@ class pos_config(osv.osv): result.append((record.id, record.name + ' ('+session.user_id.name+')')) #, '+states[session.state]+')')) return result - - def _default_payment_journal(self, cr, uid, context=None): - res = self.pool.get('account.journal').search(cr, uid, [('type', 'in', ('bank','cash'))], limit=2) - return res or [] - 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 @@ -107,7 +122,6 @@ class pos_config(osv.osv): 'state' : POS_CONFIG_STATE[0][0], 'shop_id': _default_shop, 'journal_id': _default_sale_journal, - 'journal_ids': _default_payment_journal, 'group_by' : True, } @@ -148,45 +162,20 @@ class pos_session(osv.osv): ('closed', 'Closed & Posted'), ] - def _compute_cash_journal_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.journal_id.id - break - return result - - 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 - - def _compute_controls(self, cr, uid, ids, fieldnames, args, context=None): - result = {} + def _compute_cash_all(self, cr, uid, ids, fieldnames, args, context=None): + result = dict() for record in self.browse(cr, uid, ids, context=context): - has_opening_control = False - has_closing_control = False - - for journal in record.config_id.journal_ids: - if journal.opening_control == True: - has_opening_control = True - if journal.closing_control == True: - has_closing_control = True - - if has_opening_control and has_closing_control: - break - - values = { - 'has_opening_control': has_opening_control, - 'has_closing_control': has_closing_control, + result[record.id] = { + 'cash_journal_id' : False, + 'cash_register_id' : False, + 'cash_control' : False, } - result[record.id] = values + for st in record.statement_ids: + if st.journal_id.cash_control == True: + result[record.id]['cash_control'] = True + result[record.id]['cash_journal_id'] = st.journal_id.id + result[record.id]['cash_register_id'] = st.id return result @@ -212,12 +201,17 @@ class pos_session(osv.osv): required=True, readonly=True, select=1), - 'cash_journal_id' : fields.function(_compute_cash_journal_id, method=True, - type='many2one', relation='account.journal', - string='Cash Journal', store=True), - 'cash_register_id' : fields.function(_compute_cash_register_id, method=True, - type='many2one', relation='account.bank.statement', - string='Cash Register', store=True), + 'cash_control' : fields.function(_compute_cash_all, + multi='cash', + type='boolean', string='Has Cash Control'), + 'cash_journal_id' : fields.function(_compute_cash_all, + multi='cash', + type='many2one', relation='account.journal', + string='Cash Journal', store=True), + 'cash_register_id' : fields.function(_compute_cash_all, + multi='cash', + 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', @@ -261,8 +255,6 @@ class pos_session(osv.osv): 'order_ids' : fields.one2many('pos.order', 'session_id', 'Orders'), 'statement_ids' : fields.one2many('account.bank.statement', 'pos_session_id', 'Bank Statement', readonly=True), - 'has_opening_control' : fields.function(_compute_controls, string='Has Opening Control', multi='control', type='boolean'), - 'has_closing_control' : fields.function(_compute_controls, string='Has Closing Control', multi='control', type='boolean'), } _defaults = { @@ -372,10 +364,8 @@ class pos_session(osv.osv): def wkf_action_closing_control(self, cr, uid, ids, context=None): for session in self.browse(cr, uid, ids, context=context): for statement in session.statement_ids: - if statement.id <> session.cash_register_id.id: - if statement.balance_end<>statement.balance_end_real: - self.pool.get('account.bank.statement').write(cr, uid, - [statement.id], {'balance_end_real': statement.balance_end}) + if statement != session.cash_register_id and 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): @@ -388,7 +378,7 @@ class pos_session(osv.osv): 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 and st.journal_id.cash_control == True: if st.difference > 0.0: name= _('Point of Sale Profit') account_id = st.journal_id.profit_account_id.id @@ -406,6 +396,9 @@ class pos_session(osv.osv): 'account_id': account_id }, context=context) + if st.journal_id.type == 'bank': + st.write({'balance_end_real' : st.balance_end}) + getattr(st, 'button_confirm_%s' % st.journal_id.type)(context=context) self._confirm_orders(cr, uid, ids, context=context) self.write(cr, uid, ids, {'state' : 'closed'}, context=context) @@ -731,7 +724,7 @@ class pos_order(osv.osv): 'pos_statement_id' : order_id, 'journal_id' : journal_id, 'type' : 'customer', - 'ref' : order.name, + 'ref' : order.session_id.name, }) statement_line_obj.create(cr, uid, args, context=context) @@ -1084,6 +1077,7 @@ class account_bank_statement_line(osv.osv): _columns= { 'pos_statement_id': fields.many2one('pos.order', ondelete='cascade'), } + account_bank_statement_line() class pos_order_line(osv.osv): @@ -1284,8 +1278,30 @@ class product_product(osv.osv): help="If you want to sell this product through the point of sale, select the category it belongs to."), 'to_weight' : fields.boolean('To Weight', help="This category contains products that should be weighted, mainly used for the self-checkout interface"), } + + def _default_pos_categ_id(self, cr, uid, context=None): + proxy = self.pool.get('ir.model.data') + + try: + category_id = proxy.get_object_reference(cr, uid, 'point_of_sale', 'categ_others')[1] + except ValueError: + values = { + 'name' : 'Others', + } + category_id = self.pool.get('pos.category').create(cr, uid, values, context=context) + values = { + 'name' : 'categ_others', + 'model' : 'pos.category', + 'module' : 'point_of_sale', + 'res_id' : category_id, + } + proxy.create(cr, uid, values, context=context) + + return category_id + _defaults = { 'to_weight' : False, + 'pos_categ_id' : _default_pos_categ_id, } def edit_ean(self, cr, uid, ids, context): diff --git a/addons/point_of_sale/point_of_sale_demo.xml b/addons/point_of_sale/point_of_sale_demo.xml index db8caaadf3b..47256279c59 100644 --- a/addons/point_of_sale/point_of_sale_demo.xml +++ b/addons/point_of_sale/point_of_sale_demo.xml @@ -8,7 +8,7 @@ 0410200000005 - + @@ -36,6 +36,10 @@ + + + + diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index 0f8e5e57e5f..0e906186285 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -126,7 +126,7 @@ - Sales + Orders pos.order @@ -138,6 +138,7 @@ + @@ -791,8 +792,7 @@ - - + @@ -878,10 +878,10 @@