From d4febfe788a819dbdf749e022bbac3181a2b7167 Mon Sep 17 00:00:00 2001 From: Fabien Pinckaers <fp@tinyerp.com> Date: Sun, 25 Sep 2011 16:09:30 +0200 Subject: [PATCH] [IMP+FIX] Complete cleaning of point_of_sale module - refactorisation of the code: 2000 lines of code removed - fixed all the bugs - support for tax included/excluded prices - fixed rounding troubles - don't print the ticket if partial payment - cleaning features: - workflow reviewed: New -> Done -> Posted / Invoiced - generation of journal entries/invoice is now correct - only one picking per PoS order - wizard to apply global discount (on each lines) - useability: - reviewed the main point_of_sale screen - statements are open by default - removed non-useful features - advances (you use a special product for this) - contracts numbers - refund with exchange (you just create a new sale with negatives qty) - removed validation steps - scan product wizard - clean and complete YAML tests (work in progress) bzr revid: fp@tinyerp.com-20110925140930-s6zibvn51k3914in --- addons/point_of_sale/__openerp__.py | 11 +- addons/point_of_sale/point_of_sale.py | 943 ++++-------------- addons/point_of_sale/point_of_sale_demo.xml | 316 +++--- .../point_of_sale/point_of_sale_sequence.xml | 8 +- addons/point_of_sale/point_of_sale_view.xml | 152 +-- .../point_of_sale/point_of_sale_workflow.xml | 2 +- addons/point_of_sale/report/__init__.py | 4 +- addons/point_of_sale/report/pos_details.py | 4 +- addons/point_of_sale/report/pos_invoice.py | 2 +- .../point_of_sale/report/pos_order_report.py | 21 +- .../report/pos_order_report_view.xml | 134 ++- addons/point_of_sale/report/pos_receipt.rml | 4 - .../report/pos_receipt_with_remboursment.py | 83 -- .../report/pos_receipt_with_remboursment.rml | 131 --- .../pos_receipt_without_remboursment.py | 83 -- .../pos_receipt_without_remboursment.rml | 138 --- addons/point_of_sale/report/pos_report.py | 4 +- .../test/point_of_sale_report.yml | 68 -- .../point_of_sale/test/point_of_sale_test.yml | 578 +++-------- addons/point_of_sale/wizard/__init__.py | 3 - .../point_of_sale/wizard/pos_add_product.py | 98 -- .../point_of_sale/wizard/pos_add_product.xml | 41 - addons/point_of_sale/wizard/pos_box_out.py | 11 - addons/point_of_sale/wizard/pos_discount.py | 65 +- addons/point_of_sale/wizard/pos_discount.xml | 27 +- addons/point_of_sale/wizard/pos_payment.py | 205 +--- addons/point_of_sale/wizard/pos_payment.xml | 58 +- addons/point_of_sale/wizard/pos_return.py | 15 - .../point_of_sale/wizard/pos_return_view.xml | 9 +- .../point_of_sale/wizard/pos_scan_product.py | 51 - .../wizard/pos_scan_product_view.xml | 34 - 31 files changed, 695 insertions(+), 2608 deletions(-) delete mode 100644 addons/point_of_sale/report/pos_receipt_with_remboursment.py delete mode 100644 addons/point_of_sale/report/pos_receipt_with_remboursment.rml delete mode 100644 addons/point_of_sale/report/pos_receipt_without_remboursment.py delete mode 100644 addons/point_of_sale/report/pos_receipt_without_remboursment.rml delete mode 100644 addons/point_of_sale/wizard/pos_add_product.py delete mode 100644 addons/point_of_sale/wizard/pos_add_product.xml delete mode 100644 addons/point_of_sale/wizard/pos_scan_product.py delete mode 100644 addons/point_of_sale/wizard/pos_scan_product_view.xml diff --git a/addons/point_of_sale/__openerp__.py b/addons/point_of_sale/__openerp__.py index 3bd0f188581f..75d23c2ca060 100644 --- a/addons/point_of_sale/__openerp__.py +++ b/addons/point_of_sale/__openerp__.py @@ -39,14 +39,13 @@ Main features : """, 'author': 'OpenERP SA', 'images': ['images/cash_registers.jpeg', 'images/pos_analysis.jpeg','images/register_analysis.jpeg','images/sale_order_pos.jpeg','images/product_pos.jpeg'], - 'depends': ['sale', 'delivery'], + 'depends': ['sale'], 'init_xml': [], 'update_xml': [ 'security/point_of_sale_security.xml', 'security/ir.model.access.csv', 'wizard/pos_details.xml', - 'wizard/pos_add_product.xml', 'wizard/pos_confirm.xml', 'wizard/pos_discount.xml', 'wizard/pos_get_sale.xml', @@ -64,8 +63,6 @@ Main features : 'wizard/pos_payment_report_user.xml', 'wizard/pos_payment_report.xml', 'wizard/pos_payment.xml', - 'wizard/pos_scan_product_view.xml', - 'wizard/pos_return_view.xml', 'point_of_sale_report.xml', 'point_of_sale_view.xml', 'report/pos_order_report_view.xml', @@ -75,7 +72,11 @@ Main features : 'account_statement_view.xml', 'account_statement_report.xml', ], - 'demo_xml': ['point_of_sale_demo.xml','account_statement_demo.xml'], + 'demo_xml': [ + 'point_of_sale_demo.xml', + 'account_statement_demo.xml', + 'test/00_register_open.yml' + ], 'test': ['test/point_of_sale_test.yml', 'test/point_of_sale_report.yml', ], diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index c90e325c48ec..b23ba71d0658 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -42,125 +42,23 @@ class pos_config_journal(osv.osv): pos_config_journal() - -class pos_company_discount(osv.osv): - """ Company Discount and Cashboxes """ - _inherit = 'res.company' - - _columns = { - 'company_discount': fields.float('Max Discount(%)', digits_compute=dp.get_precision('Point Of Sale')), - 'max_diff': fields.float('Max Difference for Cashboxes', digits_compute=dp.get_precision('Point Of Sale Discount')), - } - -pos_company_discount() - class pos_order(osv.osv): - """ Point of sale gives business owners a convenient way of checking out customers - and of recording sales """ - _name = "pos.order" _description = "Point of Sale" - _order = "date_order, create_date desc" + _order = "id desc" def unlink(self, cr, uid, ids, context=None): for rec in self.browse(cr, uid, ids, context=context): - for rec_statement in rec.statement_ids: - if (rec_statement.statement_id and rec_statement.statement_id.state == 'confirm') or rec.state == 'done': - raise osv.except_osv(_('Invalid action !'), _('Cannot delete a point of sale which is closed or contains confirmed cashboxes!')) + if rec.state not in ('draft','cancel'): + raise osv.except_osv(_('Unable to Delete !'), _('In order to delete a sale, it must be new or cancelled.')) return super(pos_order, self).unlink(cr, uid, ids, context=context) - def onchange_partner_pricelist(self, cr, uid, ids, part=False, context=None): - - """ Changed price list on_change of partner_id""" + def onchange_partner_id(self, cr, uid, ids, part=False, context=None): if not part: return {'value': {}} pricelist = self.pool.get('res.partner').browse(cr, uid, part, context=context).property_product_pricelist.id return {'value': {'pricelist_id': pricelist}} - def _amount_total(self, cr, uid, ids, field_name, arg, context=None): - """ Calculates amount_tax of order line - @param field_names: Names of fields. - @return: Dictionary of values """ - cr.execute(""" - SELECT - p.id, - COALESCE(SUM( - l.price_unit*l.qty*(1-(l.discount/100.0)))::decimal(16,2), 0 - ) AS amount - FROM pos_order p - LEFT OUTER JOIN pos_order_line l ON (p.id = l.order_id) - WHERE p.id IN %s GROUP BY p.id """,(tuple(ids),)) - res = dict(cr.fetchall()) - for rec in self.browse(cr, uid, ids, context=context): - if rec.partner_id \ - and rec.partner_id.property_account_position \ - and rec.partner_id.property_account_position.tax_ids: - res[rec.id] = res[rec.id] - rec.amount_tax - else : - res[rec.id] = res[rec.id] + rec.amount_tax - return res - - def _get_date_payment2(self, cr, uid, ids, context=None, *a): - # Todo need to check this function - """ Find payment Date - @param field_names: Names of fields. - @return: Dictionary of values """ - res = {} - val = None - for order in self.browse(cr, uid, ids, context=context): - cr.execute("SELECT date_payment FROM pos_order WHERE id = %s", (order.id,)) - date_p = cr.fetchone() - date_p = date_p and date_p[0] or None - if date_p: - res[order.id] = date_p - return res - if order.invoice_id: - cr.execute(" SELECT MAX(l.date) " - " FROM account_move_line l, account_move m, account_invoice i, account_move_reconcile r, pos_order o " - " WHERE i.move_id = m.id AND l.move_id = m.id AND l.reconcile_id = r.id AND o.id = %s AND o.invoice_id = i.id", - (order.id,)) - else: - cr.execute("SELECT MAX(l.date) from account_move_line l " - "left join account_bank_statement abs on (l.statement_id=abs.id)" - "left join account_bank_statement_line absl on (absl.statement_id=abs.id) " - "left join pos_order p on (p.id=absl.pos_statement_id) " - "left join account_account a on (a.id=absl.account_id) " - "where p.id=%s and l.reconcile_id is not NULL and a.reconcile=True", (order.id,)) - val = cr.fetchone() - val = val and val[0] or None - if val: - res[order.id] = val - return res - - def _get_date_payment(self, cr, uid, ids, context, *a): - """ Find Validation Date - @return: Dictionary of values """ - res = {} - val = None - for order in self.browse(cr, uid, ids): - cr.execute("SELECT date_validation FROM pos_order WHERE id = %s", (order.id,)) - date_p = cr.fetchone() - date_p = date_p and date_p[0] or None - if date_p: - res[order.id] = date_p - return res - discount_allowed = order.company_id.company_discount - for line in order.lines: - if line.discount > discount_allowed: - return {order.id: None } - if order.amount_paid == order.amount_total and not date_p: - cr.execute("SELECT MAX(date) FROM account_bank_statement_line WHERE pos_statement_id = %s", (order.id,)) - val = cr.fetchone() - val = val and val[0] or None - if order.invoice_id and order.invoice_id.move_id and not date_p and not val: - for o in order.invoice_id.move_id.line_id: - if o.balance == 0: - if val < o.date_created: - val = o.date_created - if val: - res[order.id] = val - return res - def _amount_all(self, cr, uid, ids, name, args, context=None): tax_obj = self.pool.get('account.tax') cur_obj = self.pool.get('res.currency') @@ -171,45 +69,30 @@ class pos_order(osv.osv): 'amount_return':0.0, 'amount_tax':0.0, } - val = val1 = 0.0 + val1 = val2 = 0.0 cur = order.pricelist_id.currency_id for payment in order.statement_ids: res[order.id]['amount_paid'] += payment.amount res[order.id]['amount_return'] += (payment.amount < 0 and payment.amount or 0) for line in order.lines: val1 += line.price_subtotal_incl - if order.price_type != 'tax_excluded': - res[order.id]['amount_tax'] = reduce(lambda x, y: x+round(y['amount'], 2), - tax_obj.compute_inv(cr, uid, line.product_id.taxes_id, - line.price_unit * \ - (1-(line.discount or 0.0)/100.0), line.qty), - res[order.id]['amount_tax']) - elif line.qty != 0.0: - for c in tax_obj.compute_all(cr, uid, line.product_id.taxes_id, \ - line.price_unit * (1-(line.discount or 0.0)/100.0), \ - line.qty, line.product_id, line.order_id.partner_id)['taxes']: - val += c.get('amount', 0.0) - res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val) - res[order.id]['amount_total'] = res[order.id]['amount_tax'] + cur_obj.round(cr, uid, cur, val1) + val2 += line.price_subtotal + res[order.id]['amount_tax'] = cur_obj.round(cr, uid, cur, val1-val2) + res[order.id]['amount_total'] = cur_obj.round(cr, uid, cur, val1) return res - def _sale_journal_get(self, cr, uid, context=None): - """ To get sale journal for this order - @return: journal """ - journal_obj = self.pool.get('account.journal') - res = journal_obj.search(cr, uid, [('type', '=', 'sale')], limit=1) + 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 _shop_get(self, cr, uid, context=None): - """ To get Shop for this order - @return: Shop id """ + 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 = {} - default.update({ + d = { 'state': 'draft', 'partner_id': False, 'invoice_id': False, @@ -217,279 +100,117 @@ class pos_order(osv.osv): 'picking_id': False, 'statement_ids': [], 'nb_print': 0, - 'pickings': [], 'name': self.pool.get('ir.sequence').get(cr, uid, 'pos.order'), - }) - return super(pos_order, self).copy(cr, uid, id, default, context=context) - - def _get_v( self, cr, uid, ids, *args): - """ Changed the Validation state of order - @return: State """ - res_obj = self.pool.get('res.users') - company_disc = self.browse(cr, uid, ids) - list_jrnl = [] - r = {} - if not company_disc: - comp = res_obj.browse(cr, uid, uid).company_id.company_discount or 0.0 - else: - comp = company_disc[0] and company_disc[0].company_id and company_disc[0].company_id.company_discount or 0.0 - cr.execute("SELECT discount FROM pos_order_line WHERE order_id = %s AND discount <= %s", (ids[0], comp)) - res = cr.fetchone() - cr.execute("SELECT discount FROM pos_order_line WHERE order_id = %s AND discount > %s", (ids[0], comp)) - res2 = cr.fetchone() - cr.execute("SELECT journal_id FROM account_bank_statement_line WHERE pos_statement_id = %s ", (ids[0], )) - res3 = cr.fetchall() - for r in res3: - cr.execute("SELECT id FROM account_journal WHERE name = '%s' AND special_journal = 't'", (r[0], )) - res3 = cr.fetchone() - is_special = res3 and res3[0] or None - if is_special: - list_jrnl.append(is_special) - for order in self.browse(cr, uid, ids): - if order.state in ('paid', 'done', 'invoiced') and res and not res2 and not len(list_jrnl): - r[order.id] = 'accepted' - return r + } + d.update(default) + return super(pos_order, self).copy(cr, uid, id, d, context=context) _columns = { - 'name': fields.char('Order Description', size=64, required=True, + 'name': fields.char('Order Ref', size=64, required=True, states={'draft': [('readonly', False)]}, readonly=True), 'company_id':fields.many2one('res.company', 'Company', required=True, readonly=True), - 'num_sale': fields.char('Internal Note', size=64), '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), - 'date_validation': fields.function(_get_date_payment, - string='Validation Date', - type='date', select=True, store=True), - 'date_payment': fields.function(_get_date_payment2, - string='Payment Date', - type='date', select=True, store=True), - 'date_validity': fields.date('Validity Date', required=True), 'user_id': fields.many2one('res.users', 'Connected Salesman', help="Person who uses the the cash register. It could be a reliever, a student or an interim employee."), - 'user_salesman_id': fields.many2one('res.users', 'Cashier', required=True, help="User who is logged into the system."), - 'sale_manager': fields.many2one('res.users', 'Salesman Manager'), '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'), 'amount_return': fields.function(_amount_all, 'Returned', digits_compute=dp.get_precision('Point Of Sale'), multi='all'), 'lines': fields.one2many('pos.order.line', 'order_id', 'Order Lines', states={'draft': [('readonly', False)]}, readonly=True), - 'price_type': fields.selection([ - ('tax_excluded','Tax excluded')], - 'Price Method', required=True), 'statement_ids': fields.one2many('account.bank.statement.line', 'pos_statement_id', 'Payments', states={'draft': [('readonly', False)]}, readonly=True), 'pricelist_id': fields.many2one('product.pricelist', 'Pricelist', required=True, states={'draft': [('readonly', False)]}, readonly=True), 'partner_id': fields.many2one('res.partner', 'Customer', change_default=True, select=1, states={'draft': [('readonly', False)], 'paid': [('readonly', False)]}), - 'state': fields.selection([('draft', 'Quotation'), - ('payment', 'Payment'), - ('advance','Advance'), - ('paid', 'Paid'), - ('done', 'Done'), + + 'state': fields.selection([('draft', 'New'), + ('paid', 'Done'), + ('done', 'Posted'), ('invoiced', 'Invoiced'), - ('cancel', 'Cancel')], + ('cancel', 'Cancelled')], 'State', readonly=True), + 'invoice_id': fields.many2one('account.invoice', 'Invoice'), - 'account_move': fields.many2one('account.move', 'Account Entry', readonly=True), - 'pickings': fields.one2many('stock.picking', 'pos_order', 'Picking', readonly=True), - 'picking_id': fields.many2one('stock.picking', 'Last Output Picking', readonly=True), - 'first_name': fields.char('First Name', size=64), + 'account_move': fields.many2one('account.move', 'Journal Entry', readonly=True), + '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), - 'invoice_wanted': fields.boolean('Create Invoice'), - 'note_2': fields.char('Customer Note', size=64), - 'type_rec': fields.char('Type of Receipt', size=64), - 'remboursed': fields.boolean('Remboursed'), - 'contract_number': fields.char('Contract Number', size=512, select=1), - 'journal_entry': fields.boolean('Journal Entry'), } - def _select_pricelist(self, cr, uid, context=None): - """ To get default pricelist for the order - @param name: Names of fields. - @return: pricelist ID - """ + def _default_pricelist(self, cr, uid, context=None): res = self.pool.get('sale.shop').search(cr, uid, [], context=context) if res: shop = self.pool.get('sale.shop').browse(cr, uid, res[0], context=context) return shop.pricelist_id and shop.pricelist_id.id or False return False - def _journal_default(self, cr, uid, context=None): - """ To get default pricelist for the order - @param name: Names of fields. - @return: journal ID - """ - journal_list = self.pool.get('account.journal').search(cr, uid, [('type', '=', 'cash')]) - return journal_list and journal_list[0] or False - _defaults = { - 'user_salesman_id':lambda self, cr, uid, context: uid, 'user_id': lambda self, cr, uid, context: uid, - 'sale_manager': lambda self, cr, uid, context: uid, 'state': 'draft', - 'price_type': 'tax_excluded', 'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'pos.order'), 'date_order': lambda *a: time.strftime('%Y-%m-%d %H:%M:%S'), - 'date_validity': lambda *a: (datetime.today() + relativedelta(months=+6)).strftime('%Y-%m-%d'), 'nb_print': 0, 'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id, - 'sale_journal': _sale_journal_get, - 'invoice_wanted': False, - 'shop_id': _shop_get, - 'pricelist_id': _select_pricelist, + 'sale_journal': _default_sale_journal, + 'shop_id': _default_shop, + 'pricelist_id': _default_pricelist, } - - def test_order_lines(self, cr, uid, order, context=None): - """ Test order line is created or not for the order - @param name: Names of fields. - @return: True - """ - if not order.lines: - raise osv.except_osv(_('Error'), _('No order lines defined for this sale.')) - - wf_service = netsvc.LocalService("workflow") - wf_service.trg_validate(uid, 'pos.order', order.id, 'paid', cr) - return True - - def dummy_button(self, cr, uid, order, context=None): - return True - def test_paid(self, cr, uid, ids, context=None): - """ Test all amount is paid for this order + """A Point of Sale is paid when the sum @return: True """ for order in self.browse(cr, uid, ids, context=context): if order.lines and not order.amount_total: return True if (not order.lines) or (not order.statement_ids) or \ - Decimal(str(order.amount_total)) != Decimal(str(order.amount_paid)): + (abs(order.amount_total-order.amount_paid) > 0.00001): return False return True - def _get_qty_differences(self, orders, old_picking): - """check if the customer changed the product quantity """ - order_dict = {} - for order in orders: - for line in order.lines: - order_dict[line.product_id.id] = line - - # check the quantity differences: - diff_dict = {} - for line in old_picking.move_lines: - order_line = order_dict.get(line.product_id.id) - if not order_line: - deleted = True - qty_to_delete_from_original_picking = line.product_qty - diff_dict[line.product_id.id] = (deleted, qty_to_delete_from_original_picking) - elif line.product_qty != order_line.qty: - deleted = False - qty_to_delete_from_original_picking = line.product_qty - order_line.qty - diff_dict[line.product_id.id] = (deleted, qty_to_delete_from_original_picking) - - return diff_dict - - def _split_picking(self, cr, uid, ids, context, old_picking, diff_dict): - """if the customer changes the product quantity, split the picking in two""" - # create a copy of the original picking and adjust the product qty: - picking_model = self.pool.get('stock.picking') - defaults = { - 'note': "Partial picking from customer", # add a note to tell why we create a new picking - 'name': self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.out'), # increment the sequence - } - - new_picking_id = picking_model.copy(cr, uid, old_picking.id, defaults) # state = 'draft' - new_picking = picking_model.browse(cr, uid, new_picking_id, context=context) - - for line in new_picking.move_lines: - p_id = line.product_id.id - if p_id in diff_dict: - diff = diff_dict[p_id] - deleted = diff[0] - qty_to_del = diff[1] - if deleted: # product has been deleted (customer didn't took it): - # delete this product from old picking: - for old_line in old_picking.move_lines: - if old_line.product_id.id == p_id: - old_line.write({'state': 'draft'}, context=context) # cannot delete if not draft - old_line.unlink(context=context) - elif qty_to_del > 0: # product qty has been modified (customer took less than the ordered quantity): - # subtract qty from old picking: - for old_line in old_picking.move_lines: - if old_line.product_id.id == p_id: - old_line.write({'product_qty': old_line.product_qty - qty_to_del}, context=context) - # add qty to new picking: - line.write({'product_qty': qty_to_del}, context=context) - else: # product hasn't changed (customer took it without any change): - # delete this product from new picking: - line.unlink(context=context) - else: - # delete it in the new picking: - line.unlink(context=context) - def create_picking(self, cr, uid, ids, context=None): """Create a picking for each order and validate it.""" picking_obj = self.pool.get('stock.picking') - property_obj = self.pool.get("ir.property") - move_obj = self.pool.get('stock.move') - pick_name = self.pool.get('ir.sequence').get(cr, uid, 'stock.picking.out') - orders = self.browse(cr, uid, ids, context=context) partner_obj = self.pool.get('res.partner') - for order in orders: + move_obj = self.pool.get('stock.move') + + for order in self.browse(cr, uid, ids, context=context): addr = order.partner_id and partner_obj.address_get(cr, uid, [order.partner_id.id], ['delivery']) or {} - if not order.picking_id: - new = True - picking_id = picking_obj.create(cr, uid, { - 'name': pick_name, - 'origin': order.name, - 'address_id': addr.get('delivery',False), - 'type': 'out', + picking_id = picking_obj.create(cr, uid, { + 'origin': order.name, + 'address_id': addr.get('delivery',False), + 'type': 'out', + 'company_id': order.company_id.id, + 'move_type': 'direct', + 'note': order.note or "", + 'invoice_state': 'none', + 'auto_picking': True, + }, context=context) + self.write(cr, uid, [order.id], {'picking_id': picking_id}, context=context) + location_id = order.shop_id.warehouse_id.lot_stock_id.id + output_id = order.shop_id.warehouse_id.lot_output_id.id + + for line in order.lines: + if line.product_id and line.product_id.type == 'service': + continue + if line.qty < 0: + location_id, output_id = output_id, location_id + + move_obj.create(cr, uid, { + 'name': line.name, + 'product_uom': line.product_id.uom_id.id, + 'product_uos': line.product_id.uom_id.id, + 'picking_id': picking_id, + 'product_id': line.product_id.id, + 'product_uos_qty': abs(line.qty), + 'product_qty': abs(line.qty), + 'tracking_id': False, 'state': 'draft', - 'move_type': 'direct', - 'note': 'POS notes ' + (order.note or ""), - 'invoice_state': 'none', - 'auto_picking': True, - 'pos_order': order.id, + 'location_id': location_id, + 'location_dest_id': output_id, }, context=context) - self.write(cr, uid, [order.id], {'picking_id': picking_id}, context=context) - else: - picking_id = order.picking_id.id - picking_obj.write(cr, uid, [picking_id], {'auto_picking': True}, context=context) - picking = picking_obj.browse(cr, uid, [picking_id], context=context)[0] - new = False - - # split the picking (if product quantity has changed): - diff_dict = self._get_qty_differences(orders, picking) - if diff_dict: - self._split_picking(cr, uid, ids, context, picking, diff_dict) - - if new: - for line in order.lines: - if line.product_id and line.product_id.type == 'service': - continue - prop_ids = property_obj.search(cr, uid, [('name', '=', 'property_stock_customer')], context=context) - val = property_obj.browse(cr, uid, prop_ids[0], context=context).value_reference - cr.execute("SELECT s.id FROM stock_location s, stock_warehouse w WHERE w.lot_stock_id = s.id AND w.id = %s", (order.shop_id.warehouse_id.id, )) - res = cr.fetchone() - location_id = res and res[0] or None - stock_dest_id = val.id - if line.qty < 0: - location_id, stock_dest_id = stock_dest_id, location_id - move_obj.create(cr, uid, { - 'name': '(POS %d)' % (order.id, ), - 'product_uom': line.product_id.uom_id.id, - 'product_uos': line.product_id.uom_id.id, - 'picking_id': picking_id, - 'product_id': line.product_id.id, - 'product_uos_qty': abs(line.qty), - 'product_qty': abs(line.qty), - 'tracking_id': False, - 'pos_line_id': line.id, - 'state': 'waiting', - 'location_id': location_id, - 'location_dest_id': stock_dest_id, - 'prodlot_id': line.prodlot_id and line.prodlot_id.id or False - }, context=context) + if line.qty < 0: + location_id, output_id = output_id, location_id wf_service = netsvc.LocalService("workflow") wf_service.trg_validate(uid, 'stock.picking', picking_id, 'button_confirm', cr) @@ -497,36 +218,27 @@ class pos_order(osv.osv): return True def set_to_draft(self, cr, uid, ids, *args): - """ Changes order state to draft - @return: True - """ 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 button_invalidate(self, cr, uid, ids, *args): - """ Check the access for the sale order - @return: True - """ - res_obj = self.pool.get('res.company') - try: - part_company = res_obj.browse(cr, uid, uid) and res_obj.browse(cr, uid, uid).parent_id and res_obj.browse(cr, uid, uid).parent_id.id or None - except Exception: - raise osv.except_osv(_('Error'), _('You don\'t have enough access to validate this sale!')) - if part_company: - raise osv.except_osv(_('Error'), _('You don\'t have enough access to validate this sale!')) - return True - def cancel_order(self, cr, uid, ids, context=None): """ Changes order state to cancel @return: True """ + stock_picking_obj = self.pool.get('stock.picking') + for order in self.browse(cr, uid, ids, context=context): + wf_service.trg_validate(uid, 'stock.picking', order.picking_id.id, 'button_cancel', cr) + if stock_picking_obj.browse(cr, uid, order.picking_id.id, context=context).state <> 'cancel': + raise osv.except_osv(_('Error!'), _('Unable to cancel the picking.')) self.write(cr, uid, ids, {'state': 'cancel'}, context=context) - self.cancel_picking(cr, uid, ids, context=context) return True def add_payment(self, cr, uid, order_id, data, context=None): @@ -538,8 +250,6 @@ class pos_order(osv.osv): curr_c = self.pool.get('res.users').browse(cr, uid, uid, context=context).company_id curr_company = curr_c.id order = self.browse(cr, uid, order_id, context=context) - if not order.num_sale and data['num_sale']: - self.write(cr, uid, order_id, {'num_sale': data['num_sale']}, context=context) ids_new = [] args = { 'amount': data['amount'], @@ -551,15 +261,7 @@ class pos_order(osv.osv): account_def = property_obj.get(cr, uid, 'property_account_receivable', 'res.partner', context=context) args['account_id'] = order.partner_id and order.partner_id.property_account_receivable \ and order.partner_id.property_account_receivable.id or account_def.id or curr_c.account_receivable.id - if data.get('is_acc', False): - args['is_acc'] = data['is_acc'] - args['account_id'] = prod_obj.browse(cr, uid, data['product_id'], context=context).property_account_income \ - and prod_obj.browse(cr, uid, data['product_id'], context=context).property_account_income.id - if not args['account_id']: - raise osv.except_osv(_('Error'), _('Please provide an account for the product: %s')% \ - (prod_obj.browse(cr, uid, data['product_id'], context=context).name)) args['partner_id'] = order.partner_id and order.partner_id.id or None - args['ref'] = order.contract_number or None statement_id = statement_obj.search(cr,uid, [ ('journal_id', '=', data['journal']), @@ -584,58 +286,39 @@ class pos_order(osv.osv): return statement_id - def add_product(self, cr, uid, order_id, product_id, qty, context=None): - - """Create a new order line the order""" - - line_obj = self.pool.get('pos.order.line') - values = self.read(cr, uid, order_id, ['partner_id', 'pricelist_id']) - - pricelist = values['pricelist_id'] and values['pricelist_id'][0] - product = values['partner_id'] and values['partner_id'][0] - - price = line_obj.price_by_product(cr, uid, [], - pricelist, product_id, qty, product) - - order_line_id = line_obj.create(cr, uid, { - 'order_id': order_id, - 'product_id': product_id, - 'qty': qty, - 'price_unit': price, - }, context=context) - return order_line_id, price - def refund(self, cr, uid, ids, context=None): - """Create a copy of order for refund order""" - clone_list = [] line_obj = self.pool.get('pos.order.line') - for order in self.browse(cr, uid, ids, context=context): clone_id = self.copy(cr, uid, order.id, { 'name': order.name + ' REFUND', - 'date_order': time.strftime('%Y-%m-%d'), - 'state': 'draft', - 'note': 'REFUND\n'+ (order.note or ''), - 'invoice_id': False, - 'nb_print': 0, - 'statement_ids': False, - }, context=context) + }, context=context) clone_list.append(clone_id) - for clone in self.browse(cr, uid, clone_list, context=context): for order_line in clone.lines: line_obj.write(cr, uid, [order_line.id], { 'qty': -order_line.qty - }, context=context) - return clone_list - - def action_invoice(self, cr, uid, ids, context=None): + }, context=context) - """Create a invoice of order """ + new_order = ','.join(map(str,clone_list)) + abs = { + #'domain': "[('id', 'in', ["+new_order+"])]", + 'name': _('Return Products'), + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'pos.order', + 'res_id':clone_list[0], + 'view_id': False, + 'context':context, + 'type': 'ir.actions.act_window', + 'nodestroy': True, + 'target': 'current', + } + return abs + def action_invoice(self, cr, uid, ids, context=None): inv_ref = self.pool.get('account.invoice') inv_line_ref = self.pool.get('account.invoice.line') product_obj = self.pool.get('product.product') @@ -689,22 +372,36 @@ class pos_order(osv.osv): and [(6, 0, inv_line['invoice_line_tax_id'])] or [] inv_line_ref.create(cr, uid, inv_line, context=context) - for i in inv_ids: - wf_service = netsvc.LocalService("workflow") - wf_service.trg_validate(uid, 'account.invoice', i, 'invoice_open', cr) - return inv_ids + if not inv_ids: return {} + mod_obj = self.pool.get('ir.model.data') + res = mod_obj.get_object_reference(cr, uid, 'account', 'invoice_form') + res_id = res and res[1] or False, + return { + 'name': _('PoS Invoices'), + 'view_type': 'form', + 'view_mode': 'form', + 'view_id': [res_id], + 'res_model': 'account.invoice', + 'context': "{'type':'out_invoice'}", + 'type': 'ir.actions.act_window', + 'nodestroy': True, + 'target': 'current', + 'res_id': inv_ids and inv_ids[0] or False, + } def create_account_move(self, cr, uid, ids, context=None): - """Create a account move line of order """ + """Create a account move line of order grouped by products or not.""" account_move_obj = self.pool.get('account.move') account_move_line_obj = self.pool.get('account.move.line') account_period_obj = self.pool.get('account.period') + period = account_period_obj.find(cr, uid, context=context)[0] account_tax_obj = self.pool.get('account.tax') res_obj=self.pool.get('res.users') property_obj=self.pool.get('ir.property') - period = account_period_obj.find(cr, uid, context=context)[0] for order in self.browse(cr, uid, ids, context=context): + if order.state<>'paid': continue + curr_c = res_obj.browse(cr, uid, uid).company_id comp_id = res_obj.browse(cr, order.user_id.id, order.user_id.id).company_id comp_id = comp_id and comp_id.id or False @@ -717,19 +414,14 @@ class pos_order(osv.osv): # Create an entry for the sale move_id = account_move_obj.create(cr, uid, { 'journal_id': order.sale_journal.id, - 'period_id': period, - }, context=context) + }, context=context) # Create an move for each order line for line in order.lines: tax_amount = 0 taxes = [t for t in line.product_id.taxes_id] - if order.price_type == 'tax_excluded': - computed_taxes = account_tax_obj.compute_all( - cr, uid, taxes, line.price_unit, line.qty)['taxes'] - else: - computed_taxes = account_tax_obj.compute_inv( - cr, uid, taxes, line.price_unit, line.qty) + computed = account_tax_obj.compute_all(cr, uid, taxes, line.price_unit * (100.0-line.discount) / 100.0, line.qty) + computed_taxes = computed['taxes'] for tax in computed_taxes: tax_amount += round(tax['amount'], 2) @@ -741,10 +433,7 @@ class pos_order(osv.osv): group_tax[group_key] += round(tax['amount'], 2) else: group_tax[group_key] = round(tax['amount'], 2) - if order.price_type != 'tax_excluded': - amount = line.price_subtotal - tax_amount - else: - amount = line.price_subtotal + amount = line.price_subtotal # Search for the income account if line.product_id.property_account_income.id: @@ -774,11 +463,12 @@ class pos_order(osv.osv): if tax_code_id: break + # Create a move for the line account_move_line_obj.create(cr, uid, { - 'name': "aa"+order.name, + 'name': line.name, 'date': order.date_order[:10], - 'ref': order.contract_number or order.name, + 'ref': order.name, 'quantity': line.qty, 'product_id': line.product_id.id, 'move_id': move_id, @@ -805,9 +495,9 @@ class pos_order(osv.osv): continue account_move_line_obj.create(cr, uid, { - 'name': "bb" + order.name, + 'name': "Tax" + line.name, 'date': order.date_order[:10], - 'ref': order.contract_number or order.name, + 'ref': order.name, 'product_id':line.product_id.id, 'quantity': line.qty, 'move_id': move_id, @@ -826,9 +516,9 @@ class pos_order(osv.osv): (tax_code_pos, base_code_pos, account_pos)= (0, 1, 2) for key, amount in group_tax.items(): account_move_line_obj.create(cr, uid, { - 'name': "cc" + order.name, + 'name': 'Tax', 'date': order.date_order[:10], - 'ref': order.contract_number or order.name, + 'ref': order.name, 'move_id': move_id, 'company_id': comp_id, 'quantity': line.qty, @@ -844,9 +534,9 @@ class pos_order(osv.osv): # counterpart to_reconcile.append(account_move_line_obj.create(cr, uid, { - 'name': "dd" + order.name, + 'name': order.name, 'date': order.date_order[:10], - 'ref': order.contract_number or order.name, + 'ref': order.name, 'move_id': move_id, 'company_id': comp_id, 'account_id': order_account, @@ -858,71 +548,16 @@ class pos_order(osv.osv): 'period_id': period, 'partner_id': order.partner_id and order.partner_id.id or False }, context=context)) - - - # search the account receivable for the payments: - account_receivable = order.sale_journal.default_credit_account_id.id - if not account_receivable: - raise osv.except_osv(_('Error !'), - _('There is no receivable account defined for this journal:'\ - ' "%s" (id:%d)') % (order.sale_journal.name, order.sale_journal.id, )) - for payment in order.statement_ids: - # Create one entry for the payment - if payment.is_acc: - continue - account_move_obj.create(cr, uid, { - 'journal_id': payment.statement_id.journal_id.id, - 'period_id': period, - }, context=context) - - for stat_l in order.statement_ids: - if stat_l.is_acc and len(stat_l.move_ids): - for st in stat_l.move_ids: - for s in st.line_id: - if s.credit: - account_move_line_obj.copy(cr, uid, s.id, { - 'debit': s.credit, - 'statement_id': False, - 'credit': s.debit - }) - account_move_line_obj.copy(cr, uid, s.id, { - 'statement_id': False, - 'account_id': order_account - }) - - self.write(cr, uid, order.id, {'state':'done'}, context=context) - return True - - def cancel_picking(self, cr, uid, ids, context=None): - stock_picking_obj = self.pool.get('stock.picking') - for order in self.browse(cr, uid, ids, context=context): - for picking in order.pickings: - stock_picking_obj.unlink(cr, uid, [picking.id], context=context) + self.write(cr, uid, order.id, {'state':'done', 'account_move': move_id}, context=context) return True - def action_payment(self, cr, uid, ids, context=None): - vals = {'state': 'payment'} - sequence_obj = self.pool.get('ir.sequence') - for pos in self.browse(cr, uid, ids, context=context): - create_contract_nb = False - for line in pos.lines: - if line.product_id.product_type == 'MD': - create_contract_nb = True - break - if create_contract_nb: - seq = sequence_obj.get(cr, uid, 'pos.user_%s' % pos.user_salesman_id.login) - vals['contract_number'] = '%s-%s' % (pos.user_salesman_id.login, seq) - self.write(cr, uid, ids, vals, context=context) + return self.write(cr, uid, ids, {'state': 'payment'}, context=context) def action_paid(self, cr, uid, ids, context=None): - if context is None: - context = {} - if context.get('flag', False): - self.create_picking(cr, uid, ids, context=None) - self.write(cr, uid, ids, {'state': 'paid'}, context=context) - else: - context['flag'] = True + context = context or {} + self.create_picking(cr, uid, ids, context=None) + self.write(cr, uid, ids, {'state': 'paid'}, context=context) return True def action_cancel(self, cr, uid, ids, context=None): @@ -930,43 +565,25 @@ class pos_order(osv.osv): return True def action_done(self, cr, uid, ids, context=None): - for order in self.browse(cr, uid, ids, context=context): - if not order.journal_entry: - self.create_account_move(cr, uid, ids, context=None) + self.create_account_move(cr, uid, ids, context=context) return True - def compute_state(self, cr, uid, id): - cr.execute("SELECT act.id, act.name FROM wkf_activity act " - "INNER JOIN wkf_workitem item ON act.id = item.act_id " - "INNER JOIN wkf_instance inst ON item.inst_id = inst.id " - "INNER JOIN wkf ON inst.wkf_id = wkf.id " - "WHERE wkf.osv = 'pos.order' AND inst.res_id = %s " - "ORDER BY act.name", (id, )) - return [name for id, name in cr.fetchall()] - pos_order() class account_bank_statement(osv.osv): _inherit = 'account.bank.statement' _columns= { - 'user_id': fields.many2one('res.users', ondelete='cascade', string='User', readonly=True), + 'user_id': fields.many2one('res.users', 'User', readonly=True), } _defaults = { - 'user_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).id + 'user_id': lambda self,cr,uid,c={}: uid } account_bank_statement() class account_bank_statement_line(osv.osv): _inherit = 'account.bank.statement.line' - def _get_statement_journal(self, cr, uid, ids, context, *a): - res = {} - for line in self.browse(cr, uid, ids): - res[line.id] = line.statement_id and line.statement_id.journal_id and line.statement_id.journal_id.name or None - return res _columns= { - 'journal_id': fields.function(_get_statement_journal,store=True, string='Journal', type='char', size=64), - 'am_out': fields.boolean("To count"), - 'is_acc': fields.boolean("Is accompte"), + 'journal_id': fields.related('statement_id','journal_id','name', store=True, string='Journal', type='char', size=64), 'pos_statement_id': fields.many2one('pos.order', ondelete='cascade'), } account_bank_statement_line() @@ -974,275 +591,85 @@ account_bank_statement_line() class pos_order_line(osv.osv): _name = "pos.order.line" _description = "Lines of Point of Sale" - - def _get_amount(self, cr, uid, ids, field_name, arg, context=None): - res = {} - for line in self.browse(cr, uid, ids, context=context): - price = self.price_by_product(cr, uid, ids, line.order_id.pricelist_id.id, line.product_id.id, line.qty, line.order_id.partner_id.id) - res[line.id] = price - return res - - def _amount_line_ttc(self, cr, uid, ids, field_name, arg, context=None): - res = dict.fromkeys(ids, 0.0) - account_tax_obj = self.pool.get('account.tax') - self.price_by_product_multi(cr, uid, ids) - for line in self.browse(cr, uid, ids, context=context): - tax_amount = 0.0 - taxes = [t for t in line.product_id.taxes_id] - if line.qty == 0.0: - continue - computed_taxes = account_tax_obj.compute_all(cr, uid, taxes, line.price_unit, line.qty)['taxes'] - for tax in computed_taxes: - tax_amount += tax['amount'] - if line.discount != 0.0: - res[line.id] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0) - else: - res[line.id] = line.price_unit*line.qty - res[line.id] = res[line.id] + tax_amount - return res - - def _amount_line(self, cr, uid, ids, field_name, arg, context=None): - res = {} - self.price_by_product_multi(cr, uid, ids) - for line in self.browse(cr, uid, ids, context=context): - if line.discount!=0.0: - res[line.id] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0) - else: - res[line.id] = line.price_unit * line.qty - return res + _rec_name = "product_id" def _amount_line_all(self, cr, uid, ids, field_names, arg, context=None): res = dict([(i, {}) for i in ids]) account_tax_obj = self.pool.get('account.tax') - - self.price_by_product_multi(cr, uid, ids) + cur_obj = self.pool.get('res.currency') for line in self.browse(cr, uid, ids, context=context): - for f in field_names: - if f == 'price_subtotal': - if line.discount != 0.0: - res[line.id][f] = line.price_unit * line.qty * (1 - (line.discount or 0.0) / 100.0) - else: - res[line.id][f] = line.price_unit * line.qty - elif f == 'price_subtotal_incl': - taxes = [t for t in line.product_id.taxes_id] - if line.qty == 0.0: - res[line.id][f] = 0.0 - continue - price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) - computed_taxes = account_tax_obj.compute_all(cr, uid, taxes, price, line.qty) - cur = line.order_id.pricelist_id.currency_id - res[line.id][f] = self.pool.get('res.currency').round(cr, uid, cur, computed_taxes['total']) - return res - - def price_by_product_multi(self, cr, uid, ids, context=None): - if context is None: - context = {} - res = {}.fromkeys(ids, 0.0) - lines = self.browse(cr, uid, ids, context=context) + taxes = line.product_id.taxes_id + price = line.price_unit * (1 - (line.discount or 0.0) / 100.0) + taxes = account_tax_obj.compute_all(cr, uid, line.product_id.taxes_id, price, line.qty, product=line.product_id, partner=line.order_id.partner_id or False) - pricelist_ids = [line.order_id.pricelist_id.id for line in lines] - products_by_qty_by_partner = [(line.product_id.id, line.qty, line.order_id.partner_id.id) for line in lines] + cur = line.order_id.pricelist_id.currency_id + res[line.id]['price_subtotal'] = cur_obj.round(cr, uid, cur, taxes['total']) + res[line.id]['price_subtotal_incl'] = cur_obj.round(cr, uid, cur, taxes['total_included']) + return res - price_get_multi_res = self.pool.get('product.pricelist').price_get_multi(cr, uid, pricelist_ids, products_by_qty_by_partner, context=context) + def onchange_product_id(self, cr, uid, ids, pricelist, product_id, qty=0, partner_id=False, context=None): + context = context or {} + if not product_id: + return {} + if not pricelist: + raise osv.except_osv(_('No Pricelist !'), + _('You have to select a pricelist in the sale form !\n' \ + 'Please set one before choosing a product.')) + + price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist], + product_id, qty or 1.0, partner_id)[pricelist] + + result = self.onchange_qty(cr, uid, ids, product_id, 0.0, qty, price, context=context) + result['value']['price_unit'] = price + return result + + def onchange_qty(self, cr, uid, ids, product, discount, qty, price_unit, context=None): + result = {} + if not product: + return result + account_tax_obj = self.pool.get('account.tax') + cur_obj = self.pool.get('res.currency') - for line in lines: - pricelist = line.order_id.pricelist_id.id - product_id = line.product_id + prod = self.pool.get('product.product').browse(cr, uid, product, context=context) - if not product_id: - res[line.id] = 0.0 - continue - if not pricelist: - raise osv.except_osv(_('No Pricelist !'), - _('You have to select a pricelist in the sale form !\n' \ - 'Please set one before choosing a product.')) - - #old_price = self.pool.get('product.pricelist').price_get(cr, uid, [pricelist], product_id.id, qty or 1.0, partner_id, {'uom': uom_id})[pricelist] - #print "prod_id: %s, pricelist: %s, price: %s" % (product_id.id, pricelist, price) - price = price_get_multi_res[line.product_id.id][pricelist] - #print "prod_id: %s, pricelist: %s, price2: %s" % (product_id.id, pricelist, price2) - - #if old_price != price: - # raise Exception('old_price != price') - - unit_price = price or product_id.list_price - res[line.id] = unit_price - if unit_price is False: - raise osv.except_osv(_('No valid pricelist line found !'), - _("Couldn't find a pricelist line matching this product" \ - " and quantity.\nYou have to change either the product," \ - " the quantity or the pricelist.")) - return res + taxes = prod.taxes_id + price = price_unit * (1 - (discount or 0.0) / 100.0) + taxes = account_tax_obj.compute_all(cr, uid, prod.taxes_id, price, qty, product=prod, partner=False) - def price_by_product(self, cr, uid, ids, pricelist, product_id, qty=0, partner_id=False): - if not product_id: - return 0.0 - if not pricelist: - raise osv.except_osv(_('No Pricelist !'), - _('You have to select a pricelist in the sale form !\n' \ - 'Please set one before choosing a product.')) - p_obj = self.pool.get('product.product').browse(cr, uid, [product_id])[0] - uom_id = p_obj.uom_po_id.id - price = self.pool.get('product.pricelist').price_get(cr, uid, - [pricelist], product_id, qty or 1.0, partner_id, {'uom': uom_id})[pricelist] - unit_price=price or p_obj.list_price - if unit_price is False: - raise osv.except_osv(_('No valid pricelist line found !'), - _("Couldn't find a pricelist line matching this product" \ - " and quantity.\nYou have to change either the product," \ - " the quantity or the pricelist.")) - return unit_price - - def onchange_product_id(self, cr, uid, ids, pricelist, product_id, qty=0, partner_id=False): - price = self.price_by_product(cr, uid, ids, pricelist, product_id, qty, partner_id) - self.write(cr, uid, ids, {'price_unit':price}) - pos_stot = (price * qty) - return {'value': {'price_unit': price, 'price_subtotal_incl': pos_stot}} - - def onchange_subtotal(self, cr, uid, ids, discount, price, pricelist, qty,partner_id, product_id, *a): - prod_obj = self.pool.get('product.product') - price_f = self.price_by_product(cr, uid, ids, pricelist, product_id, qty, partner_id) - prod_id = '' - if product_id: - prod_id = prod_obj.browse(cr, uid, product_id).disc_controle - disc = 0.0 - if (disc != 0.0 or prod_id) and price_f > 0: - disc = 100 - (price/price_f*100) - return {'value': {'discount': disc, 'price_unit': price_f}} - return {} - - def onchange_ded(self, cr, uid, ids, val_ded, price_u, *a): - res_obj = self.pool.get('res.users') - comp = res_obj.browse(cr, uid, uid).company_id.company_discount or 0.0 - val = 0.0 - if val_ded and price_u: - val=100.0 * val_ded / price_u - if val > comp: - return {'value': {'discount': val, 'notice': '' }} - return {'value': {'discount': val}} - - def onchange_discount(self, cr, uid, ids, discount, price, *a): - pos_order = self.pool.get('pos.order.line') - res_obj = self.pool.get('res.users') - company_disc = pos_order.browse(cr,uid,ids) - if discount: - if not company_disc: - comp=res_obj.browse(cr,uid,uid).company_id.company_discount or 0.0 - else: - comp= company_disc[0] and company_disc[0].order_id.company_id and company_disc[0].order_id.company_id.company_discount or 0.0 - - if discount > comp : - return {'value': {'notice': '', 'price_ded': price * discount * 0.01 or 0.0 }} - else: - return {'value': {'notice': 'Minimum Discount', 'price_ded': price * discount * 0.01 or 0.0 }} - else : - return {'value': {'notice': 'No Discount', 'price_ded': price * discount * 0.01 or 0.0}} - - def onchange_qty(self, cr, uid, ids, discount, qty, price, context=None): - subtotal = qty * price - if discount: - subtotal = subtotal - (subtotal * discount / 100) - return {'value': {'price_subtotal_incl': subtotal}} + result['price_subtotal'] = taxes['total'] + result['price_subtotal_incl'] = taxes['total_included'] + return {'value': result} _columns = { - 'name': fields.char('Line Description', size=512), 'company_id': fields.many2one('res.company', 'Company', required=True), + 'name': fields.char('Line No', size=32, required=True), 'notice': fields.char('Discount Notice', size=128, required=True), - 'serial_number': fields.char('Serial Number', size=128), 'product_id': fields.many2one('product.product', 'Product', domain=[('sale_ok', '=', True)], required=True, change_default=True), - 'price_unit': fields.function(_get_amount, string='Unit Price', store=True), - 'price_ded': fields.float('Discount(Amount)', digits_compute=dp.get_precision('Point Of Sale')), - 'qty': fields.float('Quantity'), - 'qty_rfd': fields.float('Refunded Quantity'), - 'price_subtotal': fields.function(_amount_line_all, multi='pos_order_line_amount', string='Subtotal w/o Tax'), - 'price_subtotal_incl': fields.function(_amount_line_all, multi='pos_order_line_amount', string='Subtotal'), + 'price_unit': fields.float(string='Unit Price', digits=(16, 2)), + 'qty': fields.float('Quantity', digits=(16, 2)), + 'price_subtotal': fields.function(_amount_line_all, multi='pos_order_line_amount', string='Subtotal w/o Tax', store=True), + 'price_subtotal_incl': fields.function(_amount_line_all, multi='pos_order_line_amount', string='Subtotal', store=True), 'discount': fields.float('Discount (%)', digits=(16, 2)), 'order_id': fields.many2one('pos.order', 'Order Ref', ondelete='cascade'), 'create_date': fields.datetime('Creation Date', readonly=True), - 'prodlot_id': fields.many2one('stock.production.lot', 'Production Lot', help="You can specify Production lot for stock move created when you validate the pos order"), } _defaults = { 'name': lambda obj, cr, uid, context: obj.pool.get('ir.sequence').get(cr, uid, 'pos.order.line'), 'qty': lambda *a: 1, 'discount': lambda *a: 0.0, - 'price_ded': lambda *a: 0.0, 'notice': lambda *a: 'No Discount', 'company_id': lambda self,cr,uid,c: self.pool.get('res.users').browse(cr, uid, uid, c).company_id.id, - } - - def create(self, cr, user, vals, context=None): - if vals.get('product_id'): - return super(pos_order_line, self).create(cr, user, vals, context=context) - return False - - def write(self, cr, user, ids, values, context=None): - if 'product_id' in values and not values['product_id']: - return False - return super(pos_order_line, self).write(cr, user, ids, values, context=context) + } def copy_data(self, cr, uid, id, default=None, context=None): if not default: default = {} default.update({ - 'prodlot_id': False, 'name': self.pool.get('ir.sequence').get(cr, uid, 'pos.order.line') }) return super(pos_order_line, self).copy_data(cr, uid, id, default, context=context) - def _scan_product(self, cr, uid, ean, qty, order): - # search pricelist_id - product_obj = self.pool.get('product.product') - pricelist_id = self.pool.get('pos.order').read(cr, uid, [order], ['pricelist_id'] ) - if not pricelist_id: - return False - - new_line = True - - product_id = product_obj.search(cr, uid, [('ean13','=', ean)]) - if not product_id: - return False - - # search price product - product = product_obj.read(cr, uid, product_id) - product_name = product[0]['name'] - price = self.price_by_product(cr, uid, 0, pricelist_id[0]['pricelist_id'][0], product_id[0], 1) - - order_line_ids = self.search(cr, uid, [('name', '=', product_name), ('order_id', '=' ,order)]) - if order_line_ids: - new_line = False - order_line_id = order_line_ids[0] - qty += self.read(cr, uid, order_line_ids[0], ['qty'])['qty'] - - if new_line: - vals = {'product_id': product_id[0], - 'price_unit': price, - 'qty': qty, - 'name': product_name, - 'order_id': order, - } - line_id = self.create(cr, uid, vals) - if not line_id: - raise osv.except_osv(_('Error'), _('Create line failed !')) - else: - vals = { - 'qty': qty, - 'price_unit': price - } - line_id = self.write(cr, uid, order_line_id, vals) - if not line_id: - raise osv.except_osv(_('Error'), _('Modify line failed !')) - line_id = order_line_id - - price_line = float(qty) * float(price) - return { - 'name': product_name, - 'product_id': product_id[0], - 'price': price, - 'price_line': price_line , - 'qty': qty - } - pos_order_line() class product_product(osv.osv): @@ -1250,20 +677,6 @@ class product_product(osv.osv): _columns = { 'income_pdt': fields.boolean('Product for Input'), 'expense_pdt': fields.boolean('Product for Output'), - 'am_out': fields.boolean('Control for Output Operations'), - 'disc_controle': fields.boolean('Discount Control'), - } - _defaults = { - 'disc_controle': True, } product_product() -class stock_picking(osv.osv): - _inherit = 'stock.picking' - _columns = { - 'pos_order': fields.many2one('pos.order', 'Pos order'), - } - -stock_picking() - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/point_of_sale_demo.xml b/addons/point_of_sale/point_of_sale_demo.xml index e95ce05256f3..c6fbefb1f6b4 100644 --- a/addons/point_of_sale/point_of_sale_demo.xml +++ b/addons/point_of_sale/point_of_sale_demo.xml @@ -4,185 +4,175 @@ <record id="base.user_demo" model="res.users"> <field name="groups_id" eval="[(4,ref('group_pos_user'))]"/> </record> - <record id="account.cash_journal" model="account.journal"> + <record id="account.cash_journal" model="account.journal"> <field eval="[(6, 0, [ref('base.user_root')])]" name="journal_users"/> </record> <record id="product_product_putmoneyforchange0" model="product.product"> - <field name="supply_method">buy</field> - <field name="uom_id" ref="product.product_uom_unit"/> - <field name="name_template">Cash In</field> - <field name="property_account_income" ref="account.cash"/> - <field name="name">Cash In</field> - <field eval="1" name="income_pdt"/> - </record> - - <record id="product_product_putmoneyforchange1" model="product.product"> - <field name="supply_method">buy</field> - <field name="uom_id" ref="product.product_uom_unit"/> - <field name="name_template">Cash Out</field> - <field name="property_account_income" ref="account.cash"/> - <field name="name">Cash Out</field> - <field eval="1" name="expense_pdt"/> - </record> + <field name="supply_method">buy</field> + <field name="uom_id" ref="product.product_uom_unit"/> + <field name="name_template">Cash In</field> + <field name="property_account_income" ref="account.cash"/> + <field name="name">Cash In</field> + <field eval="1" name="income_pdt"/> + </record> + + <record id="product_product_putmoneyforchange1" model="product.product"> + <field name="supply_method">buy</field> + <field name="uom_id" ref="product.product_uom_unit"/> + <field name="name_template">Cash Out</field> + <field name="property_account_income" ref="account.cash"/> + <field name="name">Cash Out</field> + <field eval="1" name="expense_pdt"/> + </record> - <record id="account_invoice_invoicefrompospos0" model="account.invoice"> - <field name="origin">POS/019</field> - <field name="reference">POS/019</field> - <field name="number">SAJ/2010/010</field> - <field name="journal_id" ref="account.sales_journal"/> - <field name="currency_id" ref="base.EUR"/> - <field name="address_invoice_id" ref="base.res_partner_address_8invoice"/> - <field name="user_id" ref="base.user_root"/> - <field name="address_contact_id" ref="base.res_partner_address_8"/> - <field name="reference_type">none</field> - <field name="company_id" ref="base.main_company"/> - <field name="state">open</field> - <field name="type">out_invoice</field> - <field name="internal_number">SAJ/2010/010</field> - <field name="account_id" ref="account.a_recv"/> - <field eval="0" name="reconciled"/> - <field eval="450.0" name="residual"/> - <field name="move_name">/</field> - <field name="date_invoice" eval="time.strftime('%Y-%m-%d')"/> - <field name="period_id" ref="account.period_10"/> - <field eval="450.0" name="amount_untaxed"/> - <field model="account.move" name="move_id" search="[('name', '=', u'SAJ/2010/010')]"/> - <field eval="450.0" name="amount_total"/> - <field name="partner_id" ref="base.res_partner_agrolait"/> - <field name="name">Invoice from POS: POS/019</field> - </record> - <record id="account_invoice_line_pcbasicpc0" model="account.invoice.line"> - <field name="uos_id" ref="product.product_uom_unit"/> - <field name="account_id" ref="account.a_recv"/> - <field name="name">[PC1] Basic PC</field> - <field model="account.invoice" name="invoice_id" search="[('name', '=', 'Invoice from POS: POS/019')]"/> - <field eval="450.0" name="price_unit"/> - <field eval="450.0" name="price_subtotal"/> - <field name="company_id" ref="base.main_company"/> - <field eval="[(6,0,[])]" name="invoice_line_tax_id"/> - <field eval="1.0" name="quantity"/> - <field name="partner_id" ref="base.res_partner_agrolait"/> - <field name="product_id" ref="product.product_product_pc1"/> - </record> - <record id="pos_order_pos11" model="pos.order"> - <field name="sale_journal" ref="account.sales_journal"/> - <field eval="0" name="journal_entry"/> - <field name="date_validity">2011-04-07</field> - <field name="shop_id" ref="sale.shop"/> - <field name="user_salesman_id" ref="base.user_root"/> - <field name="date_order" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> - <field name="partner_id" ref="base.res_partner_agrolait"/> - <field eval="1" name="nb_print"/> - <field name="user_id" ref="base.user_root"/> - <field name="company_id" ref="base.main_company"/> - <field eval="1" name="invoice_wanted"/> - <field name="state">paid</field> - <field name="sale_manager" ref="base.user_root"/> - <field name="pricelist_id" ref="product.list0"/> - <field name="date_validation" eval="time.strftime('%Y-%m-%d')"/> - <field name="name">POS/019</field> - <field name="price_type">tax_excluded</field> - <field model="account.invoice" name="invoice_id" search="[('name', '=', u'Invoice from POS: POS/019')]"/> - <field eval="0" name="remboursed"/> - <field model="stock.picking" name="picking_id" search="[('name', '=', u'OUT/00019')]"/> - </record> - <record id="account_bank_statement_0" model="account.bank.statement"> - <field name="user_id" ref="base.user_root"/> - <field name="name">10</field> - <field name="state">open</field> - <field name="journal_id" ref="account.sales_journal"/> - <field name="company_id" ref="base.main_company"/> - <field name="period_id" ref="account.period_10"/> - <field name="date" eval="time.strftime('%Y-%m-%d')"/> - </record> - <record id="account_bank_statement_line_paymentpos0" model="account.bank.statement.line"> - <field name="partner_id" ref="base.res_partner_agrolait"/> - <field model="account.bank.statement" name="statement_id" search="[('name', '=', u'10')]"/> - <field name="type">general</field> - <field model="pos.order" name="pos_statement_id" search="[('name', '=', u'POS/019')]"/> - <field name="company_id" ref="base.main_company"/> - <field name="account_id" ref="account.a_recv"/> - <field name="journal_id">Cash Journal - (test)</field> - <field eval="[(6,0,[])]" name="move_ids"/> - <field name="date" eval="time.strftime('%Y-%m-%d')"/> - <field eval="450.0" name="amount"/> - <field eval="0" name="is_acc"/> - <field eval="0" name="am_out"/> - <field name="name">Payment POS/019</field> - - </record> - - <record id="stock_picking_out0" model="stock.picking"> - <field name="origin">POS/019</field> - <field model="pos.order" name="pos_order" search="[('name', '=', u'POS/019')]"/> - <field name="date_done" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> - <field eval="1" name="auto_picking"/> - <field name="move_type">direct</field> - <field name="company_id" ref="base.main_company"/> - <field name="note">POS notes </field> - <field name="state">done</field> - <field name="type">out</field> - <field name="min_date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> - <field name="date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> - <field name="name">OUT/00019</field> - <field name="invoice_state">none</field> - <field name="max_date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> - </record> - <record id="stock_move_stockmovepos0" model="stock.move"> - <field name="origin">POS/019</field> - <field eval="1.0" name="product_uos_qty"/> - <field name="product_uom" ref="product.product_uom_unit"/> - <field eval="1.0" name="product_qty"/> - <field name="product_uos" ref="product.product_uom_unit"/> - <field name="location_id" ref="stock.stock_location_stock"/> - <field name="priority">1</field> - <field eval="0" name="auto_validate"/> - <field name="company_id" ref="base.main_company"/> - <field name="state">done</field> - <field eval="[(6,0,[])]" name="move_history_ids"/> - <field name="date_expected" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> - <field name="date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> - <field name="name">Stock move (POS 12)</field> - <field eval="[(6,0,[])]" name="move_history_ids2"/> - <field name="product_id" ref="product.product_product_pc1"/> - <field name="date_planned" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> - <field name="location_dest_id" ref="stock.stock_location_customers"/> - <field model="stock.picking" name="picking_id" search="[('name', '=', u'OUT/00019')]"/> - </record> - <record id="pos_order_line_orderline0" model="pos.order.line"> - <field name="notice">No Discount</field> - <field name="product_id" ref="product.product_product_pc1"/> - <field model="pos.order" name="order_id" search="[('name', '=', u'POS/019')]"/> - <field eval="450.0" name="price_unit"/> - <field name="company_id" ref="base.main_company"/> - <field eval="1.0" name="qty"/> - <field name="name">Order Line/07</field> - </record> - + <record id="account_invoice_invoicefrompospos0" model="account.invoice"> + <field name="origin">POS/019</field> + <field name="reference">POS/019</field> + <field name="number">SAJ/2010/010</field> + <field name="journal_id" ref="account.sales_journal"/> + <field name="currency_id" ref="base.EUR"/> + <field name="address_invoice_id" ref="base.res_partner_address_8invoice"/> + <field name="user_id" ref="base.user_root"/> + <field name="address_contact_id" ref="base.res_partner_address_8"/> + <field name="reference_type">none</field> + <field name="company_id" ref="base.main_company"/> + <field name="state">open</field> + <field name="type">out_invoice</field> + <field name="internal_number">SAJ/2010/010</field> + <field name="account_id" ref="account.a_recv"/> + <field eval="0" name="reconciled"/> + <field eval="450.0" name="residual"/> + <field name="move_name">/</field> + <field name="date_invoice" eval="time.strftime('%Y-%m-%d')"/> + <field name="period_id" ref="account.period_10"/> + <field eval="450.0" name="amount_untaxed"/> + <field model="account.move" name="move_id" search="[('name', '=', u'SAJ/2010/010')]"/> + <field eval="450.0" name="amount_total"/> + <field name="partner_id" ref="base.res_partner_agrolait"/> + <field name="name">Invoice from POS: POS/019</field> + </record> + <record id="account_invoice_line_pcbasicpc0" model="account.invoice.line"> + <field name="uos_id" ref="product.product_uom_unit"/> + <field name="account_id" ref="account.a_recv"/> + <field name="name">[PC1] Basic PC</field> + <field model="account.invoice" name="invoice_id" search="[('name', '=', 'Invoice from POS: POS/019')]"/> + <field eval="450.0" name="price_unit"/> + <field eval="450.0" name="price_subtotal"/> + <field name="company_id" ref="base.main_company"/> + <field eval="[(6,0,[])]" name="invoice_line_tax_id"/> + <field eval="1.0" name="quantity"/> + <field name="partner_id" ref="base.res_partner_agrolait"/> + <field name="product_id" ref="product.product_product_pc1"/> + </record> + <record id="pos_order_pos11" model="pos.order"> + <field name="sale_journal" ref="account.sales_journal"/> + <field eval="0" name="journal_entry"/> + <field name="shop_id" ref="sale.shop"/> + <field name="date_order" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> + <field name="partner_id" ref="base.res_partner_agrolait"/> + <field eval="1" name="nb_print"/> + <field name="user_id" ref="base.user_root"/> + <field name="company_id" ref="base.main_company"/> + <field name="state">paid</field> + <field name="pricelist_id" ref="product.list0"/> + <field name="name">POS/019</field> + <field name="price_type">tax_excluded</field> + <field model="account.invoice" name="invoice_id" search="[('name', '=', u'Invoice from POS: POS/019')]"/> + <field model="stock.picking" name="picking_id" search="[('name', '=', u'OUT/00019')]"/> + </record> + <record id="account_bank_statement_0" model="account.bank.statement"> + <field name="user_id" ref="base.user_root"/> + <field name="name">10</field> + <field name="state">open</field> + <field name="journal_id" ref="account.sales_journal"/> + <field name="company_id" ref="base.main_company"/> + <field name="period_id" ref="account.period_10"/> + <field name="date" eval="time.strftime('%Y-%m-%d')"/> + </record> + <record id="account_bank_statement_line_paymentpos0" model="account.bank.statement.line"> + <field name="partner_id" ref="base.res_partner_agrolait"/> + <field model="account.bank.statement" name="statement_id" search="[('name', '=', u'10')]"/> + <field name="type">general</field> + <field model="pos.order" name="pos_statement_id" search="[('name', '=', u'POS/019')]"/> + <field name="company_id" ref="base.main_company"/> + <field name="account_id" ref="account.a_recv"/> + <field name="journal_id">Cash Journal - (test)</field> + <field eval="[(6,0,[])]" name="move_ids"/> + <field name="date" eval="time.strftime('%Y-%m-%d')"/> + <field eval="450.0" name="amount"/> + <field name="name">Payment POS/019</field> + + </record> + + <record id="stock_picking_out0" model="stock.picking"> + <field name="origin">POS/019</field> + <field model="pos.order" name="pos_order" search="[('name', '=', u'POS/019')]"/> + <field name="date_done" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> + <field eval="1" name="auto_picking"/> + <field name="move_type">direct</field> + <field name="company_id" ref="base.main_company"/> + <field name="note">POS notes </field> + <field name="state">done</field> + <field name="type">out</field> + <field name="min_date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> + <field name="date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> + <field name="name">OUT/00019</field> + <field name="invoice_state">none</field> + <field name="max_date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> + </record> + <record id="stock_move_stockmovepos0" model="stock.move"> + <field name="origin">POS/019</field> + <field eval="1.0" name="product_uos_qty"/> + <field name="product_uom" ref="product.product_uom_unit"/> + <field eval="1.0" name="product_qty"/> + <field name="product_uos" ref="product.product_uom_unit"/> + <field name="location_id" ref="stock.stock_location_stock"/> + <field name="priority">1</field> + <field eval="0" name="auto_validate"/> + <field name="company_id" ref="base.main_company"/> + <field name="state">done</field> + <field eval="[(6,0,[])]" name="move_history_ids"/> + <field name="date_expected" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> + <field name="date" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> + <field name="name">Stock move (POS 12)</field> + <field eval="[(6,0,[])]" name="move_history_ids2"/> + <field name="product_id" ref="product.product_product_pc1"/> + <field name="date_planned" eval="time.strftime('%Y-%m-%d %H:%M:%S')"/> + <field name="location_dest_id" ref="stock.stock_location_customers"/> + <field model="stock.picking" name="picking_id" search="[('name', '=', u'OUT/00019')]"/> + </record> + <record id="pos_order_line_orderline0" model="pos.order.line"> + <field name="notice">No Discount</field> + <field name="product_id" ref="product.product_product_pc1"/> + <field model="pos.order" name="order_id" search="[('name', '=', u'POS/019')]"/> + <field eval="450.0" name="price_unit"/> + <field name="company_id" ref="base.main_company"/> + <field eval="1.0" name="qty"/> + <field name="name">Order Line/07</field> + </record> + <!--Resource: pos.order--> - <record id="order_pos1" model="pos.order"> + <record id="order_pos1" model="pos.order"> <field model="sale.shop" name="shop_id" search="[]"/> - <field model="res.users" name="user_salesman_id" search="[]"/> <field name="user_id" ref="base.user_root"/> <field model="res.partner" name="partner_id" search="[]"/> <field name="price_type">tax_excluded</field> <field model="product.pricelist" name="pricelist_id" search="[]"/> - </record> - - <record id="order_pos2" model="pos.order"> + </record> + + <record id="order_pos2" model="pos.order"> <field model="sale.shop" name="shop_id" search="[]"/> - <field model="res.users" name="user_salesman_id" search="[]"/> <field name="user_id" ref="base.user_root"/> <field model="res.partner" name="partner_id" search="[]"/> <field name="price_type">tax_excluded</field> <field model="product.pricelist" name="pricelist_id" search="[]"/> - </record> - - <!--Resource: pos.order.line--> - - <record id="line1_pos" model="pos.order.line"> + </record> + + <!--Resource: pos.order.line--> + + <record id="line1_pos" model="pos.order.line"> <field name="order_id" ref="order_pos1"/> <field name="date_planned" eval="time.strftime('%Y-%m-%d')"/> <field name="name">[PC3] Medium PC</field> @@ -218,6 +208,6 @@ <field name="discount">0.10</field> <field name="notice">Discount Applied</field> </record> - + </data> </openerp> diff --git a/addons/point_of_sale/point_of_sale_sequence.xml b/addons/point_of_sale/point_of_sale_sequence.xml index 399dccc634f8..d2d4bcc313c0 100644 --- a/addons/point_of_sale/point_of_sale_sequence.xml +++ b/addons/point_of_sale/point_of_sale_sequence.xml @@ -13,8 +13,8 @@ <record model="ir.sequence" id="seq_pos_order"> <field name="name">POS Order</field> <field name="code">pos.order</field> - <field name="prefix">POS/</field> - <field name="padding">3</field> + <field name="prefix">POS</field> + <field name="padding">6</field> </record> <record model="ir.sequence.type" id="seq_type_pos_order_line"> @@ -24,8 +24,8 @@ <record model="ir.sequence" id="seq_pos_order_line"> <field name="name">POS order line</field> <field name="code">pos.order.line</field> - <field name="prefix">Order Line/</field> - <field name="padding">2</field> + <field name="prefix">POSL</field> + <field name="padding">4</field> </record> </data> diff --git a/addons/point_of_sale/point_of_sale_view.xml b/addons/point_of_sale/point_of_sale_view.xml index a8552cddc15b..0f81d4a24f5d 100644 --- a/addons/point_of_sale/point_of_sale_view.xml +++ b/addons/point_of_sale/point_of_sale_view.xml @@ -13,51 +13,47 @@ <field name="type">form</field> <field name="arch" type="xml"> <form string="Sales Order POS"> - <group col="6" colspan="4"> + <group col="7" colspan="4"> <field name="name"/> <field name="date_order"/> - <field name="shop_id" widget="selection"/> - <field name="partner_id" on_change="onchange_partner_pricelist(partner_id)" groups="base.group_extended"/> - <field name="contract_number" groups="base.group_extended"/> + <field name="partner_id" on_change="onchange_partner_id(partner_id)" groups="base.group_extended"/> + <button name="invoice" string="Invoice" icon="gtk-apply" type="workflow" states="paid" attrs="{'invisible': ['|',('partner_id','=',False),('state','<>','paid')]}"/> </group> <notebook colspan="4"> <page string="Sale Order"> <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)" width="275" /> - <field name="qty" on_change="onchange_qty(discount, qty, price_unit)"/> - <field name="price_ded" on_change="onchange_ded(price_ded, price_subtotal_incl,price_unit)" invisible="1"/> - <field name="price_unit"/> - <field name="discount" on_change="onchange_discount(discount,price_unit)" /> - <field name="price_subtotal" /> - <field name="price_subtotal_incl" sum="Subtotal"/> + <field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,qty,parent.partner_id)"/> + <field name="qty" on_change="onchange_qty(product_id, discount, qty, price_unit, context)"/> + <field name="price_unit" on_change="onchange_qty(product_id, discount, qty, price_unit, context)"/> + <field name="discount" on_change="onchange_qty(product_id, discount, qty, price_unit, context)"/> + <field name="price_subtotal"/> + <field name="price_subtotal_incl"/> </tree> <form string="Order lines"> - <field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,qty,parent.partner_id)" width="275"/> - <field name="qty"/> - <field name="qty_rfd" groups="base.group_extended"/> - <field name="discount" on_change="onchange_discount(discount,price_unit)" /> - <field name="price_ded" on_change="onchange_ded(price_ded, price_unit)" /> - <field name="price_unit"/> + <field name="product_id" on_change="onchange_product_id(parent.pricelist_id,product_id,qty,parent.partner_id)"/> + <field name="qty" on_change="onchange_qty(product_id, discount, qty, price_unit, context)"/> + <field name="discount" on_change="onchange_qty(product_id, discount, qty, price_unit, context)"/> + <field name="price_unit" on_change="onchange_qty(product_id, discount, qty, price_unit, context)"/> + <field name="price_subtotal" invisible="1"/> + <field name="price_subtotal_incl" invisible="1"/> <field name="notice"/> - <field name="serial_number"/> - <field name="prodlot_id" domain="[('product_id','=',product_id)]"/> </form> </field> <group colspan="4" col="7"> <field name="amount_tax"/> <field name="amount_total"/> + <button name="button_dummy" string="Update" icon="gtk-execute" states="draft" /> + <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" /> - <button name="%(action_add_product)d" string="Add product" type="action" icon="gtk-ok" states="advance" groups="base.group_extended"/> - <button name="%(action_pos_payment)d" string="Make Payment" icon="terp-dolar" type="action" states="draft,advance" /> + <button name="%(action_pos_payment)d" string="Payment" icon="gtk-apply" type="action" states="draft"/> + <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"/> - <button name="set_to_draft" string="Set to draft" states="paid" icon="gtk-execute" type="object" /> - <button name="%(action_view_pos_return)d" string="Return Picking" type="action" icon="gtk-ok" states="paid" - attrs="{'invisible':[('state','!=','paid'),('state','!=','invoiced')]}" context="{'return':'return'}" /> </group> </page> <page string="Payment"> @@ -74,22 +70,25 @@ </form> </field> </page> - <page string="Extra Info"> - <group colspan="2" col="2" name="Type"> - <separator string="Other Information" colspan="4"/> - <field name="user_salesman_id" /> + <page string="Extra Info" groups="base.group_extended"> + <group colspan="2" col="2"> + <separator string="General Information" colspan="2"/> <field name="company_id" groups="base.group_multi_company"/> - <field name="price_type" /> - <field name="user_id" string="Salesman" groups="base.group_extended"/> + <field name="shop_id" widget="selection"/> + <field name="user_id"/> + <field name="pricelist_id" domain="[('type','=','sale')]"/> + <field name="picking_id" readonly="1" groups="base.group_extended"/> </group> - <group colspan="2" col="2" name="Type"> - <separator string="Dates" colspan="4"/> - <field name="date_validation" /> - <field name="date_payment" groups="base.group_extended"/> - </group> - <group colspan="4"> - <field name="sale_journal" domain="[('type','=','sale')]" widget="selection" invisible="1"/> - <field name="pricelist_id" domain="[('type','=','sale')]" widget="selection" invisible="0"/> + <group colspan="2" col="3"> + <separator string="Accounting Information" colspan="3"/> + <field name="sale_journal" domain="[('type','=','sale')]"/> + <button name="done" string="Post Entries" icon="gtk-apply" type="workflow" states="paid"/> + <field name="invoice_id" colspan="2" readonly="1" + attrs="{'invisible':[('state','<>','invoiced')]}"/> + <button name="%(pos_invoice_report)d" string="Re-Print" + icon="gtk-print" type="action" attrs="{'invisible':[('state','<>','invoiced')]}"/> + <field name="account_move" colspan="3" readonly="1" + attrs="{'invisible':[('state','<>','done')]}"/> </group> </page> <page string="Notes" > @@ -116,8 +115,6 @@ <field name="name"/> <field name="partner_id"/> <field name="date_order"/> - <field name="date_validation"/> - <field name="date_payment"/> <field name="user_id"/> <field name="invoice_id"/> <field name="amount_total" sum="Amount total"/> @@ -132,8 +129,7 @@ <field name="type">search</field> <field name="arch" type="xml"> <search string="Search Sales Order"> - <filter icon="terp-document-new" string="Quotations" domain="[('state','=','draft')]"/> - <filter icon="terp-check" string="Running" domain="[('state','in',('payment','advance'))]"/> + <filter icon="terp-document-new" string="New" domain="[('state','=','draft')]"/> <separator orientation="vertical"/> <field name="name"/> <field name="partner_id"/> @@ -158,60 +154,6 @@ <menuitem action="product.product_normal_action" id="menu_pos_products" parent="menu_point_of_sale_product" sequence="2" name="Products"/> - <!-- POS Order view (date_payment) --> - <record model="ir.actions.act_window" id="action_pos_pos_form_user"> - <field name="name">Point of Sale</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="view_id" ref="view_pos_order_tree"/> - <field name="domain">['|',('state','=','advance')]</field> - <field name="context">{"search_default_user_id":uid}</field> - <field name="search_view_id" ref="view_pos_order_filter"/> - - </record> - - <record model="ir.actions.act_window" id="action_pos_order_accepted"> - <field name="name">Accepted Sales</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">[('state','=', 'paid')]</field> - <field name="context">{"search_default_user_id":uid}</field> - <field name="search_view_id" ref="view_pos_order_filter"/> - </record> - <record model="ir.actions.act_window" id="action_pos_order_tree2"> - <field name="name">Point of Sale</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">[('date_order','<=', time.strftime('%Y-%m-%d 23:59:59'))]</field> - <field name="context">{"search_default_user_id":uid}</field> - <field name="search_view_id" ref="view_pos_order_filter"/> - </record> - - <record model="ir.actions.act_window" id="action_pos_order_tree3"> - <field name="name">Point of Sale</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="context">{"search_default_user_id":uid}</field> - <field name="search_view_id" ref="view_pos_order_filter"/> - </record> - <record model="ir.actions.act_window" id="action_pos_order_tree_open"> - <field name="name">Opened Sales</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">form,tree</field> - <field name="context">{"search_default_user_id":uid}</field> - <field name="search_view_id" ref="view_pos_order_filter"/> - </record> - <record model="ir.ui.view" id="view_pos_order_line"> <field name="name">Sale lines</field> <field name="model">pos.order.line</field> @@ -632,20 +574,6 @@ <field name="view_mode">tree,calendar,form,graph</field> <field name="domain">[('date_order','like',time.strftime('%Y-%m'))]</field> </record> - <!-- Sales by margin ends --> - <record model="ir.ui.view" id="view_company_form_pos"> - <field name="name">view.company.form.pos</field> - <field name="model">res.company</field> - <field name="type">form</field> - <field name="inherit_id" ref="base.view_company_form"/> - <field name="arch" type="xml"> - <field name="currency_id" position="after"> - <separator string="Point of Sale" colspan="4"/> - <field name="company_discount" /> - <field name="max_diff" /> - </field> - </field> - </record> <record id="product_normal_form_view" model="ir.ui.view"> <field name="name">product.normal.form.inherit</field> @@ -657,8 +585,6 @@ <separator string="Point of Sale" colspan="2"/> <field name="income_pdt"/> <field name="expense_pdt"/> - <field name="am_out"/> - <field name="disc_controle"/> </field> </field> </record> @@ -693,7 +619,6 @@ <separator string="Miscelleanous" colspan="2"/> <field name="income_pdt"/> <field name="expense_pdt"/> - <field name="am_out"/> <field name="disc_controle"/> <field name="company_id" groups="base.group_extended,base.group_multi_company"/> </group> @@ -782,7 +707,6 @@ <field name="arch" type="xml"> <tree string="POS Orders lines"> <field name="order_id" /> - <field name="serial_number" /> <field name="create_date" /> <field name="product_id" /> <field name="qty" /> diff --git a/addons/point_of_sale/point_of_sale_workflow.xml b/addons/point_of_sale/point_of_sale_workflow.xml index c325c4951c9e..4058af2696fb 100644 --- a/addons/point_of_sale/point_of_sale_workflow.xml +++ b/addons/point_of_sale/point_of_sale_workflow.xml @@ -69,7 +69,7 @@ </record> <record model="workflow.transition" id="trans_paid_cancel"> - <field name="act_from" ref="act_paid"/> + <field name="act_from" ref="act_draft"/> <field name="act_to" ref="act_cancel"/> <field name="signal">cancel</field> </record> diff --git a/addons/point_of_sale/report/__init__.py b/addons/point_of_sale/report/__init__.py index d7355af03575..c537119efe94 100644 --- a/addons/point_of_sale/report/__init__.py +++ b/addons/point_of_sale/report/__init__.py @@ -33,10 +33,8 @@ import pos_sales_user_today import pos_payment_report_date import pos_payment_report_user import pos_sales_user_today_current_user -import pos_receipt_with_remboursment -import pos_receipt_without_remboursment import pos_report import pos_order_report import report_cash_register -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_details.py b/addons/point_of_sale/report/pos_details.py index 84f3de8258f6..4c23a005674a 100644 --- a/addons/point_of_sale/report/pos_details.py +++ b/addons/point_of_sale/report/pos_details.py @@ -97,7 +97,7 @@ class pos_details(report_sxw.rml_parse): def _get_sum_dis_2(self,form,user): res4=[] - self.cr.execute ("select sum(pol.price_ded * pol.qty)" \ + self.cr.execute ("select sum(pol.qty)" \ "from pos_order as po,pos_order_line as pol,product_product as pp,product_template as pt, res_users as ru,res_company as rc " \ "where pt.id=pp.product_tmpl_id and pp.id=pol.product_id and po.id = pol.order_id and po.state IN ('paid') " \ "and to_char(date_trunc('day',po.date_order),'YYYY-MM-DD')::date >= %s and to_char(date_trunc('day',po.date_order),'YYYY-MM-DD')::date <= %s " \ @@ -215,4 +215,4 @@ class pos_details(report_sxw.rml_parse): report_sxw.report_sxw('report.pos.details', 'pos.order', 'addons/point_of_sale_singer/report/pos_details.rml', parser=pos_details, header='internal') -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_invoice.py b/addons/point_of_sale/report/pos_invoice.py index 7a89b1019564..0e1cd98fb479 100644 --- a/addons/point_of_sale/report/pos_invoice.py +++ b/addons/point_of_sale/report/pos_invoice.py @@ -55,4 +55,4 @@ class pos_invoice(report_sxw.rml_parse): report_sxw.report_sxw('report.pos.invoice', 'pos.order', 'addons/account/report/account_print_invoice.rml', parser= pos_invoice) -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_order_report.py b/addons/point_of_sale/report/pos_order_report.py index 006814574950..ceb20a11a369 100644 --- a/addons/point_of_sale/report/pos_order_report.py +++ b/addons/point_of_sale/report/pos_order_report.py @@ -35,9 +35,7 @@ class pos_order_report(osv.osv): 'day': fields.char('Day', size=128, readonly=True), 'partner_id':fields.many2one('res.partner', 'Partner', readonly=True), 'product_id':fields.many2one('product.product', 'Product', readonly=True), - 'state': fields.selection([('draft', 'Draft'), ('payment', 'Payment'), - ('advance','Advance'), - ('paid', 'Paid'), ('done', 'Done'), ('invoiced', 'Invoiced'), ('cancel', 'Cancel')], + 'state': fields.selection([('draft', 'New'), ('paid', 'Closed'), ('done', 'Synchronized'), ('invoiced', 'Invoiced'), ('cancel', 'Cancelled')], 'State'), 'user_id':fields.many2one('res.users', 'Salesman', readonly=True), 'price_total':fields.float('Total Price', readonly=True), @@ -49,9 +47,6 @@ class pos_order_report(osv.osv): 'product_qty':fields.integer('# of Qty', readonly=True), 'journal_id': fields.many2one('account.journal', 'Journal'), 'delay_validation': fields.integer('Delay Validation'), - 'delay_payment': fields.integer('Delay Payment'), - 'date_validation': fields.date('Validation Date', required=True), - 'date_payment': fields.date('Payment Date', required=True), } _order = 'date desc' @@ -65,10 +60,9 @@ class pos_order_report(osv.osv): to_date(to_char(s.date_order, 'dd-MM-YYYY'),'dd-MM-YYYY') as date, sum(l.qty * u.factor) as product_qty, sum(l.qty * l.price_unit) as price_total, - sum(l.qty * l.price_ded) as total_discount, + sum(l.qty * l.discount) as total_discount, (sum(l.qty*l.price_unit)/sum(l.qty * u.factor))::decimal(16,2) as average_price, - sum(cast(to_char(date_trunc('day',s.date_validation) - date_trunc('day',s.date_order),'DD') as int)) as delay_validation, - sum(cast(to_char(date_trunc('day',s.date_payment) - date_trunc('day',s.date_order),'DD') as int)) as delay_payment, + sum(cast(to_char(date_trunc('day',s.date_order) - date_trunc('day',s.create_date),'DD') as int)) as delay_validation, to_char(s.date_order, 'YYYY') as year, to_char(s.date_order, 'MM') as month, to_char(s.date_order, 'YYYY-MM-DD') as day, @@ -78,9 +72,7 @@ class pos_order_report(osv.osv): s.shop_id as shop_id, s.company_id as company_id, s.sale_journal as journal_id, - l.product_id as product_id, - s.date_validation, - s.date_payment + l.product_id as product_id from pos_order_line as l left join pos_order s on (s.id=l.order_id) left join product_template pt on (pt.id=l.product_id) @@ -88,11 +80,10 @@ class pos_order_report(osv.osv): group by to_char(s.date_order, 'dd-MM-YYYY'),to_char(s.date_order, 'YYYY'),to_char(s.date_order, 'MM'), to_char(s.date_order, 'YYYY-MM-DD'), s.partner_id,s.state, - s.user_id,s.shop_id,s.company_id,s.sale_journal,l.product_id,s.date_validation, - s.date_payment + s.user_id,s.shop_id,s.company_id,s.sale_journal,l.product_id,s.create_date having sum(l.qty * u.factor) != 0)""") pos_order_report() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/report/pos_order_report_view.xml b/addons/point_of_sale/report/pos_order_report_view.xml index 8b18bf0b57a4..41fe2c3b4d62 100644 --- a/addons/point_of_sale/report/pos_order_report_view.xml +++ b/addons/point_of_sale/report/pos_order_report_view.xml @@ -2,65 +2,62 @@ <openerp> <data> <record id="view_report_pos_order_tree" model="ir.ui.view"> - <field name="name">report.pos.order.tree</field> - <field name="model">report.pos.order</field> - <field name="type">tree</field> - <field name="arch" type="xml"> - <tree string="Point of Sale Analysis"> - <field name="date" invisible="1"/> - <field name="user_id" invisible="1"/> - <field name="year" invisible="1"/> - <field name="day" invisible="1"/> - <field name="month" invisible="1"/> - <field name="partner_id" invisible="1"/> - <field name="product_id" invisible="1"/> - <field name="shop_id" invisible="1"/> - <!--<field name="journal_id" invisible="1"/>--> - <field name="date_validation" invisible="1"/> - <field name="date_payment" invisible="1"/> + <field name="name">report.pos.order.tree</field> + <field name="model">report.pos.order</field> + <field name="type">tree</field> + <field name="arch" type="xml"> + <tree string="Point of Sale Analysis"> + <field name="date" invisible="1"/> + <field name="user_id" invisible="1"/> + <field name="year" invisible="1"/> + <field name="day" invisible="1"/> + <field name="month" invisible="1"/> + <field name="partner_id" invisible="1"/> + <field name="product_id" invisible="1"/> + <field name="shop_id" invisible="1"/> + <!--<field name="journal_id" invisible="1"/>--> <field name="company_id" invisible="1" groups="base.group_multi_company"/> - <field name="nbr" sum="# of Lines"/> - <field name="product_qty" sum="# of Qty"/> - <field name="average_price" sum="Average Price"/> - <field name="total_discount" sum="Total Discount"/> - <field name="price_total" sum="Total Price"/> - <field name="delay_validation"/> - <field name="delay_payment"/> - <!--<field name="state" invisible="1"/>--> - </tree> - </field> + <field name="nbr" sum="# of Lines"/> + <field name="product_qty" sum="# of Qty"/> + <field name="average_price" sum="Average Price"/> + <field name="total_discount" sum="Total Discount"/> + <field name="price_total" sum="Total Price"/> + <field name="delay_validation"/> + <!--<field name="state" invisible="1"/>--> + </tree> + </field> </record> <record id="view_report_pos_order_search" model="ir.ui.view"> - <field name="name">report.pos.order.search</field> - <field name="model">report.pos.order</field> - <field name="type">search</field> - <field name="arch" type="xml"> - <search string="Point of Sale Analysis"> - <group> - <filter icon="terp-go-year" string="Year" - domain="[('year','=',time.strftime('%%Y'))]" - help="POS ordered created during current year"/> - <filter icon="terp-go-month" string="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" + <field name="name">report.pos.order.search</field> + <field name="model">report.pos.order</field> + <field name="type">search</field> + <field name="arch" type="xml"> + <search string="Point of Sale Analysis"> + <group> + <filter icon="terp-go-year" string="Year" + domain="[('year','=',time.strftime('%%Y'))]" + help="POS ordered created during current year"/> + <filter icon="terp-go-month" string="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" domain="[('date','<=', time.strftime('%%Y-%%m-%%d'))]" help="POS ordered created by today"/> - <separator orientation="vertical"/> + <separator orientation="vertical"/> <filter icon="terp-dolar" string="Invoiced" domain="[('state','=',('invoiced'))]"/> - <filter icon="terp-dolar" - string="Paid" - domain="[('state','=',('paid'))]"/> + <filter icon="terp-dolar" + string="Paid" + domain="[('state','=',('paid'))]"/> <separator orientation="vertical"/> <field name="partner_id"/> <field name="user_id" widget="selection"> @@ -69,36 +66,31 @@ help="My Sales" domain="[('user_id','=',uid)]"/> </field> - </group> - <newline/> - <group expand="0" string="Extended Filters..." groups="base.group_extended"> - <field name="date_validation"/> - <field name="date_payment"/> </group> - <newline/> - <group expand="1" string="Group By..."> - <filter string="Salesman" icon="terp-personal" name="User" context="{'group_by':'user_id'}"/> - <filter string="Customer" icon="terp-personal" context="{'group_by':'partner_id'}"/> - <separator orientation="vertical"/> - <filter string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id'}"/> + <newline/> + <group expand="1" string="Group By..."> + <filter string="Salesman" icon="terp-personal" name="User" context="{'group_by':'user_id'}"/> + <filter string="Customer" icon="terp-personal" context="{'group_by':'partner_id'}"/> + <separator orientation="vertical"/> + <filter string="Product" icon="terp-accessories-archiver" context="{'group_by':'product_id'}"/> <separator orientation="vertical"/> <filter string="Day" icon="terp-go-today" context="{'group_by':'day'}" help="Day of order date"/> <filter string="Month" icon="terp-go-month" context="{'group_by':'month'}" help="Month of order date"/> <filter string="Year" icon="terp-go-year" context="{'group_by':'year'}" help="Year of order date"/> - </group> - </search> - </field> + </group> + </search> + </field> </record> <record id="action_report_pos_order_all" model="ir.actions.act_window"> - <field name="name">Point of Sale Analysis</field> - <field name="res_model">report.pos.order</field> - <field name="view_type">form</field> - <field name="view_mode">tree,graph</field> - <field name="search_view_id" ref="view_report_pos_order_search"/> - <field name="context">{'search_default_today':1,'search_default_User':1,'group_by_no_leaf':1,'group_by':[]}</field> - </record> + <field name="name">Point of Sale Analysis</field> + <field name="res_model">report.pos.order</field> + <field name="view_type">form</field> + <field name="view_mode">tree,graph</field> + <field name="search_view_id" ref="view_report_pos_order_search"/> + <field name="context">{'search_default_today':1,'search_default_User':1,'group_by_no_leaf':1,'group_by':[]}</field> + </record> - <menuitem action="action_report_pos_order_all" id="menu_report_pos_order_all" parent="menu_point_rep" sequence="3"/> - </data> + <menuitem action="action_report_pos_order_all" id="menu_report_pos_order_all" parent="menu_point_rep" sequence="3"/> + </data> </openerp> diff --git a/addons/point_of_sale/report/pos_receipt.rml b/addons/point_of_sale/report/pos_receipt.rml index b9da3f5e9a64..e3b5583a499f 100644 --- a/addons/point_of_sale/report/pos_receipt.rml +++ b/addons/point_of_sale/report/pos_receipt.rml @@ -77,7 +77,6 @@ <para style="terp_default_Centre_9">Tel : [[ address and address.phone ]]</para> <para style="terp_default_Centre_9">E-mail : [[ address and address.email ]]</para> <para style="terp_default_Centre_9">Shop : [[ o.shop_id.name ]]</para> - <para style="terp_default_Centre_9">Vendeur : [[ o.user_salesman_id.name ]]</para> <para style="terp_default_Centre_9">Date : [[ o.date_order ]]</para> <para style="P4"> <font color="white"> </font> @@ -85,12 +84,10 @@ <para style="P4"> <font color="white"> </font> </para> - <para style="P4">[[o.type_rec]]</para> <para style="P4"> <font color="white"> </font> </para> <para style="P4">N° : [[ o.name ]]</para> - <para style="P4">Contract : [[ o.contract_number ]]</para> <blockTable colWidths="68.0,68.0,68.0" style="Table3"> <tr> <td> @@ -165,6 +162,5 @@ </td> </tr> </blockTable> - <para style="P3">[[o.note_2]]</para> </story> </document> diff --git a/addons/point_of_sale/report/pos_receipt_with_remboursment.py b/addons/point_of_sale/report/pos_receipt_with_remboursment.py deleted file mode 100644 index c600a9e27547..000000000000 --- a/addons/point_of_sale/report/pos_receipt_with_remboursment.py +++ /dev/null @@ -1,83 +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 time -from report import report_sxw -import pooler - -class order(report_sxw.rml_parse): - - def __init__(self, cr, uid, name, context): - super(order, self).__init__(cr, uid, name, context=context) - - user = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, uid) - partner = user.company_id.partner_id - - self.localcontext.update({ - 'time': time, - 'disc': self.discount, - 'net': self.netamount, - 'get_journal_amt': self._get_journal_amt, - 'address': partner.address and partner.address[0] or False, - }) - - def netamount(self, order_line_id): - sql = 'select (qty*price_unit) as net_price from pos_order_line where id = %s' - self.cr.execute(sql, (order_line_id,)) - res = self.cr.fetchone() - return res[0] - - def discount(self, order_id): - sql = 'select discount, price_unit, qty from pos_order_line where order_id = %s ' - self.cr.execute(sql, (order_id,)) - res = self.cr.fetchall() - dsum = 0 - for line in res: - if line[0] != 0: - dsum = dsum +(line[2] * (line[0]*line[1]/100)) - return dsum - - def _get_journal_amt(self, order_id): - lst=[] - sql = """ select aj.name from account_bank_statement as abs - LEFT JOIN account_bank_statement_line as absl ON abs.id = absl.statement_id - LEFT JOIN account_journal as aj ON aj.id = abs.journal_id - WHERE absl.pos_statement_id = %d"""%(order_id.id) - self.cr.execute(sql) - res = self.cr.fetchone() - if not res: - return ['', 0.0] - lst.append(res[0]) # todo: improve - sql2 = """ select sum(absl.amount) as amt from account_bank_statement as abs - LEFT JOIN account_bank_statement_line as absl ON abs.id = absl.statement_id - LEFT JOIN account_journal as aj ON aj.id = abs.journal_id - where aj.name = '%s' """%(res[0]) - self.cr.execute(sql2) - res1 = self.cr.fetchone() - if res1: - lst.append(res1[0]) - else: - lst.append(0.0) - return lst - -report_sxw.report_sxw('report.pos.receipt.with.remboursment', 'pos.order', 'addons/point_of_sale/report/pos_receipt_with_remboursment.rml', parser=order, header=False) - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/point_of_sale/report/pos_receipt_with_remboursment.rml b/addons/point_of_sale/report/pos_receipt_with_remboursment.rml deleted file mode 100644 index 9c25d5f4a89a..000000000000 --- a/addons/point_of_sale/report/pos_receipt_with_remboursment.rml +++ /dev/null @@ -1,131 +0,0 @@ -<?xml version="1.0"?> -<document filename="test.pdf"> - <template pageSize="(224.0,842.0)" title="Receipt with reimbursement " author="OpenERP S.A. (sales@openerp.com)" allowSplitting="20"> - <pageTemplate id="first"> - <frame id="first" x1="0.0" y1="0.0" width="224" height="842"/> - </pageTemplate> - </template> - <stylesheet> - <blockTableStyle id="Standard_Outline"> - <blockAlignment value="LEFT"/> - <blockValign value="TOP"/> - </blockTableStyle> - <blockTableStyle id="Tableau2"> - <blockAlignment value="LEFT"/> - <blockValign value="TOP"/> - <blockBackground colorName="#ffffff" start="0,0" stop="0,0"/> - <blockBackground colorName="#ffffff" start="1,0" stop="1,0"/> - <blockBackground colorName="#ffffff" start="2,0" stop="2,0"/> - </blockTableStyle> - <blockTableStyle id="Tableau3"> - <blockAlignment value="LEFT"/> - <blockValign value="TOP"/> - </blockTableStyle> - <blockTableStyle id="Table1"> - <blockAlignment value="LEFT"/> - <blockValign value="TOP"/> - </blockTableStyle> - <initialize> - <paraStyle name="all" alignment="justify"/> - </initialize> - <paraStyle name="terp_default_address" fontName="Helvetica" fontSize="10.0" leading="13" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_Bold_9" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_Centre_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_Right_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_Bold_9_Right" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="P1" fontName="Times-Roman" fontSize="6.0" leading="8" alignment="LEFT"/> - <paraStyle name="terp_default_8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> - - <paraStyle name="P2" fontName="Times-Bold" fontSize="9.0" leading="11" alignment="CENTER"/> - <paraStyle name="P3" fontName="Times-Roman" fontSize="7.0" leading="9" alignment="CENTER"/> - <paraStyle name="P30" fontName="Times-Roman" fontSize="7.0" leading="9" alignment="LEFT"/> - <paraStyle name="P31" fontName="Times-Bold" fontSize="8.0" leading="9" alignment="CENTER" backColor="#dddddd"/> - <paraStyle name="P4" fontName="Times-Roman" fontSize="8.0" leading="10" alignment="CENTER"/> - <paraStyle name="P5" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="CENTER" spaceBefore="30"/> - <paraStyle name="P6" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="RIGHT"/> - <paraStyle name="P7" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="RIGHT"/> - <paraStyle name="P8" fontName="Times-BoldItalic" fontSize="6.0" leading="8" alignment="LEFT"/> - <paraStyle name="P9" fontName="Times-Roman" fontSize="6.0" leading="8" alignment="LEFT"/> - <paraStyle name="P10" fontName="Times-Roman" fontSize="7.0" leading="9" alignment="RIGHT"/> - <paraStyle name="P11" rightIndent="0.0" leftIndent="-3.0" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="CENTER"/> - <paraStyle name="P12" rightIndent="0.0" leftIndent="-2.0" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="CENTER"/> - <paraStyle name="P13" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="RIGHT"/> - <paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/> - <paraStyle name="P14" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="LEFT"/> - <paraStyle name="Standard" fontName="Times-Roman"/> - <paraStyle name="Text body" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/> - <paraStyle name="Heading" fontName="Helvetica" fontSize="14.0" leading="17" spaceBefore="12.0" spaceAfter="6.0"/> - <paraStyle name="List" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/> - <paraStyle name="Table Contents" fontName="Times-Roman"/> - <paraStyle name="Table Heading" fontName="Times-Roman" alignment="CENTER"/> - <paraStyle name="Caption" fontName="Times-Roman" fontSize="12.0" leading="15" spaceBefore="6.0" spaceAfter="6.0"/> - <paraStyle name="Index" fontName="Times-Roman"/> - </stylesheet> - <story> - [[ repeatIn(objects,'o') ]] - <para style="terp_default_8">[[ repeatIn(objects,'o') ]]</para> - <para style="terp_header_Centre">[[o.user_id.company_id.name]]</para> - <para style="terp_default_Centre_9">[[ address and address.street ]], [[ address and address.zip ]] [[ address and address.city ]]</para> - <para style="terp_default_Centre_9">[[ address and address.country_id.name ]]</para> - <para style="terp_default_Centre_9">Tel : [[ address and address.phone ]]</para> - <para style="terp_default_Centre_9">E-mail : [[ address and address.email ]]</para> - <para style="terp_default_Centre_9">Salesman : [[ o.user_id.name ]]</para> - <para style="terp_default_Centre_9">Sale Date : [[ o.date_order ]]</para> - <para style="P5">Refund Receipt: [[o.name]]</para> - <para style="P4"> - <font color="white"> </font> - </para> - <blockTable colWidths="118.0,30.0,38.0" repeatRows="1" style="Tableau2"> - - <tr> - <td> - <para style="P5">Description</para> - </td> - <td> - <para style="P11">Qty</para> - </td> - <td> - <para style="P12">Price</para> - </td> - </tr> - </blockTable> - <section> - <para style="P8">[[ repeatIn(o.lines,'line') ]]</para> - <blockTable colWidths="100.0,30.0,55.0" style="Tableau3"> - - <tr> - <td> - <para style="P9">[[ line.product_id.name ]]</para> - </td> - <td> - <para style="P10">[[o.state=='cancel' and o.statement_ids and '-' or '']][['%.f' % line.qty ]]</para> - </td> - <td> - <para style="P10">[[o.state=='cancel' and o.statement_ids and '-' or '']][[ '%.2f' % net(line.id) ]] <font> [[ line and line.discount == 0.0 and removeParentNode('font') ]] ([[ '%.f' % line.discount ]]%)</font></para> - </td> - </tr> - </blockTable> - </section> - <blockTable colWidths="149.0,37.0" style="Table1"> - <tr> - <td> - <para style="P13">Disc : </para> - </td> - <td> - <para style="P10">[[o.state=='cancel' and o.statement_ids and '-' or '']][[ '%.2f' % (disc(o.id) or 0.0,) ]] </para> - </td> - </tr> - <tr> - <td> - <para style="P6">Total :</para> - </td> - <td> - <para style="P7">[[o.state=='cancel' and o.statement_ids and '-' or '']][['%.2f' % o.amount_total ]] [[ o.pricelist_id.currency_id.name ]]</para> - </td> - </tr> - </blockTable> - <para style="terp_default_Centre_9">[[ get_journal_amt(o)[1] ]]</para> - </story> -</document> - diff --git a/addons/point_of_sale/report/pos_receipt_without_remboursment.py b/addons/point_of_sale/report/pos_receipt_without_remboursment.py deleted file mode 100644 index d2fe0f1d542e..000000000000 --- a/addons/point_of_sale/report/pos_receipt_without_remboursment.py +++ /dev/null @@ -1,83 +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 time -from report import report_sxw -import pooler - -class order(report_sxw.rml_parse): - - def __init__(self, cr, uid, name, context): - super(order, self).__init__(cr, uid, name, context=context) - - user = pooler.get_pool(cr.dbname).get('res.users').browse(cr, uid, uid) - partner = user.company_id.partner_id - - self.localcontext.update({ - 'time': time, - 'disc': self.discount, - 'net': self.netamount, - 'get_journal_amt': self._get_journal_amt, - 'address': partner.address and partner.address[0] or False, - }) - - def netamount(self, order_line_id): - sql = 'select (qty*price_unit) as net_price from pos_order_line where id = %s' - self.cr.execute(sql, (order_line_id,)) - res = self.cr.fetchone() - return res[0] - - def discount(self, order_id): - sql = 'select discount, price_unit, qty from pos_order_line where order_id = %s ' - self.cr.execute(sql, (order_id,)) - res = self.cr.fetchall() - dsum = 0 - for line in res: - if line[0] != 0: - dsum = dsum +(line[2] * (line[0]*line[1]/100)) - return dsum - - def _get_journal_amt(self, order_id): - lst=[] - sql = """ select aj.name from account_bank_statement as abs - LEFT JOIN account_bank_statement_line as absl ON abs.id = absl.statement_id - LEFT JOIN account_journal as aj ON aj.id = abs.journal_id - WHERE absl.pos_statement_id = %d"""%(order_id.id) - self.cr.execute(sql) - res = self.cr.fetchone() - if not res: - return ['', 0.0] - lst.append(res[0]) # todo: improve - sql2 = """ select sum(absl.amount) as amt from account_bank_statement as abs - LEFT JOIN account_bank_statement_line as absl ON abs.id = absl.statement_id - LEFT JOIN account_journal as aj ON aj.id = abs.journal_id - where aj.name = '%s' """%(res[0]) - self.cr.execute(sql2) - res1 = self.cr.fetchone() - if res1: - lst.append(res1[0]) - else: - lst.append(0.0) - return lst - -report_sxw.report_sxw('report.pos.receipt.without.remboursment', 'pos.order', 'addons/point_of_sale/report/pos_receipt_without_remboursment.rml', parser=order, header=False) - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file diff --git a/addons/point_of_sale/report/pos_receipt_without_remboursment.rml b/addons/point_of_sale/report/pos_receipt_without_remboursment.rml deleted file mode 100644 index ff6ebc3132c0..000000000000 --- a/addons/point_of_sale/report/pos_receipt_without_remboursment.rml +++ /dev/null @@ -1,138 +0,0 @@ -<?xml version="1.0"?> -<document filename="test.pdf"> - <template pageSize="(224.0,842.0)" title="Receipt without reimbursement " author="OpenERP S.A. (sales@openerp.com)" allowSplitting="20"> - <pageTemplate id="first"> - <frame id="first" x1="0.0" y1="0.0" width="224" height="842"/> - </pageTemplate> - </template> - <stylesheet> - <blockTableStyle id="Standard_Outline"> - <blockAlignment value="LEFT"/> - <blockValign value="TOP"/> - </blockTableStyle> - <blockTableStyle id="Tableau2"> - <blockAlignment value="LEFT"/> - <blockValign value="TOP"/> - <blockBackground colorName="#ffffff" start="0,0" stop="0,0"/> - <blockBackground colorName="#ffffff" start="1,0" stop="1,0"/> - <blockBackground colorName="#ffffff" start="2,0" stop="2,0"/> - </blockTableStyle> - <blockTableStyle id="Tableau3"> - <blockAlignment value="LEFT"/> - <blockValign value="TOP"/> - </blockTableStyle> - <blockTableStyle id="Table1"> - <blockAlignment value="LEFT"/> - <blockValign value="TOP"/> - </blockTableStyle> - <initialize> - <paraStyle name="all" alignment="justify"/> - </initialize> - <paraStyle name="terp_default_address" fontName="Helvetica" fontSize="10.0" leading="13" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_Bold_9" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_Centre_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="CENTER" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_Right_9" fontName="Helvetica" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="terp_default_Bold_9_Right" fontName="Helvetica-Bold" fontSize="9.0" leading="11" alignment="RIGHT" spaceBefore="0.0" spaceAfter="0.0"/> - <paraStyle name="P1" fontName="Times-Roman" fontSize="6.0" leading="8" alignment="LEFT"/> - <paraStyle name="terp_default_8" fontName="Helvetica" fontSize="8.0" leading="10" alignment="LEFT" spaceBefore="0.0" spaceAfter="0.0"/> - - <paraStyle name="P2" fontName="Times-Bold" fontSize="9.0" leading="11" alignment="CENTER"/> - <paraStyle name="P3" fontName="Times-Roman" fontSize="7.0" leading="9" alignment="CENTER"/> - <paraStyle name="P30" fontName="Times-Roman" fontSize="7.0" leading="9" alignment="LEFT"/> - <paraStyle name="P31" fontName="Times-Bold" fontSize="8.0" leading="9" alignment="CENTER" backColor="#dddddd"/> - <paraStyle name="P4" fontName="Times-Roman" fontSize="8.0" leading="10" alignment="CENTER"/> - <paraStyle name="P5" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="LEFT"/> - <paraStyle name="P6" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="RIGHT"/> - <paraStyle name="P7" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="RIGHT"/> - <paraStyle name="P8" fontName="Times-BoldItalic" fontSize="6.0" leading="8" alignment="LEFT"/> - <paraStyle name="P9" fontName="Times-Roman" fontSize="6.0" leading="8" alignment="LEFT"/> - <paraStyle name="P10" fontName="Times-Roman" fontSize="7.0" leading="9" alignment="RIGHT"/> - <paraStyle name="P11" rightIndent="0.0" leftIndent="-3.0" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="CENTER"/> - <paraStyle name="P12" rightIndent="0.0" leftIndent="-2.0" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="CENTER"/> - <paraStyle name="P13" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="RIGHT"/> - <paraStyle name="terp_header_Centre" fontName="Helvetica-Bold" fontSize="12.0" leading="15" alignment="CENTER" spaceBefore="12.0" spaceAfter="6.0"/> - <paraStyle name="P14" fontName="Times-Bold" fontSize="8.0" leading="10" alignment="LEFT"/> - <paraStyle name="Standard" fontName="Times-Roman"/> - <paraStyle name="Text body" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/> - <paraStyle name="Heading" fontName="Helvetica" fontSize="14.0" leading="17" spaceBefore="12.0" spaceAfter="6.0"/> - <paraStyle name="List" fontName="Times-Roman" spaceBefore="0.0" spaceAfter="6.0"/> - <paraStyle name="Table Contents" fontName="Times-Roman"/> - <paraStyle name="Table Heading" fontName="Times-Roman" alignment="CENTER"/> - <paraStyle name="Caption" fontName="Times-Roman" fontSize="12.0" leading="15" spaceBefore="6.0" spaceAfter="6.0"/> - <paraStyle name="Index" fontName="Times-Roman"/> - </stylesheet> - <story> - [[ repeatIn(objects,'o') ]] - <para style="terp_default_8">[[ repeatIn(objects,'o') ]]</para> - <para style="terp_header_Centre">[[o.user_id.company_id.name]]</para> - <para style="terp_default_Centre_9">[[ address and address.street ]], [[ address and address.zip ]] [[ address and address.city ]]</para> - <para style="terp_default_Centre_9">[[ address and address.country_id.name ]]</para> - <para style="terp_default_Centre_9">Tel : [[ address and address.phone ]]</para> - <para style="terp_default_Centre_9">E-mail : [[ address and address.email ]]</para> - <para style="terp_default_Centre_9">Salesman : [[ o.user_id.name ]]</para> - <para style="terp_default_Centre_9">Sale Date : [[ str(o.date_order) ]]</para> - <para style="P5">Purchase Voucher : [[o.name]]</para> - <para style="P4"> - <font color="white"> </font> - </para> - <blockTable colWidths="118.0,30.0,38.0" repeatRows="1" style="Tableau2"> - - <tr> - <td> - <para style="P5">Description</para> - </td> - <td> - <para style="P11">Qty</para> - </td> - <td> - <para style="P12">Price</para> - </td> - </tr> - </blockTable> - <section> - <para style="P8">[[ repeatIn(o.lines,'line') ]]</para> - <blockTable colWidths="100.0,30.0,55.0" style="Tableau3"> - - <tr> - <td> - <para style="P9">[[ line.product_id.name ]]</para> - </td> - <td> - <para style="P10">[[o.state=='cancel' and o.statement_ids and '-' or '']][['%.f' % line.qty ]]</para> - </td> - <td> - <para style="P10">[[o.state=='cancel' and o.statement_ids and '-' or '']][[ '%.2f' % net(line.id) ]] <font> [[ line and line.discount == 0.0 and removeParentNode('font') ]] ([[ '%.f' % line.discount ]]%)</font></para> - </td> - </tr> - </blockTable> - </section> - <blockTable colWidths="149.0,37.0" style="Table1"> - <tr> - <td> - <para style="P13">Disc : </para> - </td> - <td> - <para style="P10">[[o.state=='cancel' and o.statement_ids and '-' or '']][[ '%.2f' % (disc(o.id) or 0.0,) ]] </para> - </td> - </tr> - <tr> - <td> - <para style="P6">Total :</para> - </td> - <td> - <para style="P7">[[o.state=='cancel' and o.statement_ids and '-' or '']][['%.2f' % o.amount_total ]] [[ o.pricelist_id.currency_id.name ]]</para> - </td> - </tr> - </blockTable> - <para style="terp_default_Centre_9">[[ get_journal_amt(o)[0] ]] : [[ get_journal_amt(o)[1] ]]</para> - -<!-- <section>--> -<!-- [[ repeatIn((o.state=='cancel' and o.statement_ids) and [1] or [], 'p') ]]--> -<!-- <para style="P31">--> -<!-- Ce bon est valide jusqu'au [[ time.strftime('%d/%m/%Y', time.strptime(o.date_validity,'%Y-%m-%d')) ]].--> -<!-- </para>--> -<!-- </section>--> - </story> -</document> - diff --git a/addons/point_of_sale/report/pos_report.py b/addons/point_of_sale/report/pos_report.py index cd41eb929449..1ecf80ea5194 100644 --- a/addons/point_of_sale/report/pos_report.py +++ b/addons/point_of_sale/report/pos_report.py @@ -49,7 +49,7 @@ class report_transaction_pos(osv.osv): min(absl.id) as id, count(absl.id) as no_trans, sum(absl.amount) as amount, - sum(line.price_ded) as disc, + sum((100.0-line.discount) * line.price_unit * line.qty / 100.0) as disc, to_char(date_trunc('day',absl.create_date),'YYYY-MM-DD')::text as date_create, po.user_id as user_id, po.sale_journal as journal_id, @@ -236,4 +236,4 @@ class report_sales_by_margin_pos_month(osv.osv): """) report_sales_by_margin_pos_month() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: \ No newline at end of file +# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/test/point_of_sale_report.yml b/addons/point_of_sale/test/point_of_sale_report.yml index b821dc899dff..14a4b3348000 100644 --- a/addons/point_of_sale/test/point_of_sale_report.yml +++ b/addons/point_of_sale/test/point_of_sale_report.yml @@ -34,24 +34,6 @@ if tools.config['test_report_directory']: file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-receipt report'+format), 'wb+').write(data) -- - In order to test the PDF reports defined on a Point of Sale, we will print a POS Receipt With Reimbursement Report -- - !python {model: pos.order}: | - import netsvc, tools, os - (data, format) = netsvc.LocalService('report.pos.receipt.with.remboursment').create(cr, uid, [ref('point_of_sale.order_pos1'), ref('point_of_sale.order_pos2')], {}, {}) - if tools.config['test_report_directory']: - file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-receipt with reimbursement report'+format), 'wb+').write(data) - -- - In order to test the PDF reports defined on a point of sale, we will print a POS Receipt Without Reimbursement Report -- - !python {model: pos.order}: | - import netsvc, tools, os - (data, format) = netsvc.LocalService('report.pos.receipt.without.remboursment').create(cr, uid, [ref('point_of_sale.order_pos1'), ref('point_of_sale.order_pos2')], {}, {}) - if tools.config['test_report_directory']: - file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-receipt without reimbursement report'+format), 'wb+').write(data) - - Print the POS Payment Report through the wizard - @@ -74,56 +56,6 @@ from tools import test_reports test_reports.try_report_action(cr, uid, 'action_report_pos_details',wiz_data=data_dict, context=ctx, our_module='point_of_sale') -- - I create a cash journal. -- - !record {model: account.journal, id: account_journal_cash0}: - name: 'Cash Journal' - code: 'CSJ' - type: 'cash' - view_id: account.account_journal_bank_view - sequence_id: account.sequence_journal -- - I create a record for Bank Statement. -- - !record {model: account.bank.statement, id: account_bank_statement_st0}: - name: St.05/19 - balance_end_real: 0.0 - date: !eval time.strftime('%Y-%m-%d') - journal_id: account_journal_cash0 - line_ids: - - name: statement - date: !eval "(datetime.now() + timedelta(5*31)).strftime('%Y-%m-%d')" - type: customer - account_id: account_pos_account_sales - amount: 100 - partner_id: base.res_partner_agrolait - period_id: account.period_5 - state: 'draft' -- - In order to test the PDF reports defined on a Point Of Sale, we will print a Account Statement Report -- - !python {model: account.bank.statement}: | - import netsvc, tools, os, time - (data, format) = netsvc.LocalService('report.account.statement').create(cr, uid, [ref('point_of_sale.account_bank_statement_st0')], {}, {}) - if tools.config['test_report_directory']: - file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-account_statement_report'+format), 'wb+').write(data) -- - In order to test the PDF reports defined on a Point Of Sale, we will print a POS User Product Report -- - !python {model: account.bank.statement}: | - import netsvc, tools, os, time - (data, format) = netsvc.LocalService('report.pos.user.product').create(cr, uid, [ref('point_of_sale.account_bank_statement_st0')], {}, {}) - if tools.config['test_report_directory']: - file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-user_product_report'+format), 'wb+').write(data) -- - In order to test the PDF reports defined on a Point Of Sale, we will print a POS All Close Cashbox Of the Day Report -- - !python {model: account.bank.statement}: | - import netsvc, tools, os, time - (data, format) = netsvc.LocalService('report.all.closed.cashbox.of.the.day').create(cr, uid, [ref('point_of_sale.account_bank_statement_st0')], {}, {}) - if tools.config['test_report_directory']: - file(os.path.join(tools.config['test_report_directory'], 'point_of_sale-all_closed_cash_box_of_the_day_report'+format), 'wb+').write(data) - In order to test the PDF reports defined on a Point of Sale, we will print a POS Sales User Report - diff --git a/addons/point_of_sale/test/point_of_sale_test.yml b/addons/point_of_sale/test/point_of_sale_test.yml index 6165e993240f..f565741a8a18 100644 --- a/addons/point_of_sale/test/point_of_sale_test.yml +++ b/addons/point_of_sale/test/point_of_sale_test.yml @@ -1,437 +1,173 @@ - - In order to test the POS in module, To give business owners a convenient way of checking out customers and of recording sales. - + In order to test the Point of Sale in module, I will do a full flow from the sale to the paiement and invoicing. - - I configure all details for the Customer, Salesman and Product, Account. -- - I create View Account Type. -- - !record {model: account.account.type, id: account_account_type_view0}: - close_method: none - code: View - name: View - sign: 1 -- - I create Income Account Type. -- - !record {model: account.account.type, id: account_account_type_income0}: - close_method: unreconciled - code: Income - name: Income - sign: 1 -- - I create Expense Account Type. -- - !record {model: account.account.type, id: account_account_type_expense0}: - close_method: unreconciled - code: Expense - name: Expense - sign: 1 -- - I create Cash Account Type. -- - !record {model: account.account.type, id: account_account_type_cash0}: - close_method: balance - code: Cash - name: Cash - sign: 1 -- - I create Minimal Chart Account. -- - !record {model: account.account, id: account_pos_account_minimalchart}: - code: 'x_0' - company_id: base.main_company - currency_mode: current - name: Minimal Chart - parent_left: 1 - parent_right: 12 - type: view - user_type: account_account_type_view0 -- - I create Payable Account. -- - !record {model: account.account, id: account_pos_account_payable}: - code: AP - company_id: base.main_company - currency_mode: current - name: Payable - parent_id: account_pos_account_minimalchart - parent_left: 2 - parent_right: 3 - reconcile: true - type: payable - user_type: account_account_type_expense0 -- - I create Receivable Account. -- - !record {model: account.account, id: account_pos_account_receivable}: - code: AR - company_id: base.main_company - currency_mode: current - name: Receivable - parent_id: account_pos_account_minimalchart - parent_left: 4 - parent_right: 5 - reconcile: true - type: receivable - user_type: account_account_type_income0 -- - I create Cash Account. -- - !record {model: account.account, id: account_pos_account_cash}: - code: C - company_id: base.main_company - currency_mode: current - name: Cash - parent_id: account_pos_account_minimalchart - parent_left: 6 - parent_right: 7 - type: other - user_type: account_account_type_cash0 -- - I create Purchases Account. -- - !record {model: account.account, id: account_pos_account_purchases}: - code: P - company_id: base.main_company - currency_mode: current - name: Purchases - parent_id: account_pos_account_minimalchart - parent_left: 8 - parent_right: 9 - type: other - user_type: account_account_type_expense0 -- - I create Sales Account. -- - !record {model: account.account, id: account_pos_account_sales}: - code: Sale - company_id: base.main_company - currency_mode: current - name: Sales - parent_id: account_pos_account_minimalchart - parent_left: 10 - parent_right: 11 - type: other - user_type: account_account_type_income0 -- - I create Purchase Journal - (test). -- - !record {model: account.journal, id: account_pos_account_journal_purchasejournal}: - code: PUJ - company_id: base.main_company - default_credit_account_id: account_pos_account_purchases - default_debit_account_id: account_pos_account_purchases - name: Purchase Journal - (test) - sequence_id: account.sequence_purchase_journal - type: purchase - view_id: account.account_journal_view -- - I create Sale Journal. -- - !record {model: account.journal, id: account_pos_account_journal_salejournal}: - code: SJ - company_id: base.main_company - default_credit_account_id: account_pos_account_sales - default_debit_account_id: account_pos_account_sales - name: Sale Journal - sequence_id: account.sequence_sale_journal - type: sale - view_id: account.account_journal_view -- - I create Bank Journal. -- - !record {model: account.journal, id: account_pos_account_journal_bankjournal}: - code: BNK - company_id: base.main_company - default_credit_account_id: account_pos_account_cash - default_debit_account_id: account_pos_account_cash - name: Bank Journal - sequence_id: account.sequence_journal - type: cash - view_id: account.account_journal_bank_view -- - I create property for account payable. -- - !record {model: ir.property, id: ir_property_propertyaccountexpensecateg0}: - company_id: base.main_company - fields_id: account.field_res_partner_property_account_payable - name: property_account_expense_categ - value_reference: account.account,5 -- - I create property for account receivable. -- - !record {model: ir.property, id: ir_property_propertyaccountincomecateg0}: - company_id: base.main_company - fields_id: account.field_res_partner_property_account_receivable - name: property_account_income_categ - value_reference: account.account,6 -- - I create Partner category Customers. -- - !record {model: res.partner.category, id: res_partner_category_customers0}: - name: Customers -- - I create partner -- - !record {model: res.partner, id: res_partner_cleartrail0}: - category_id: - - res_partner_category_customers0 - name: Cleartrail -- - I create partner address. -- - !record {model: res.partner.address, id: res_partner_address_1}: - partner_id: res_partner_cleartrail0 - street: onam plaza, 14 B palasia A B Road - type: contact -- - I create partner invoice address. -- - !record {model: res.partner.address, id: res_partner_address_2}: - partner_id: res_partner_cleartrail0 - type: invoice -- - I create partner delivery address. -- - !record {model: res.partner.address, id: res_partner_address_3}: - partner_id: res_partner_cleartrail0 - street: sangam house 15 B palasia, A B Road - type: delivery -- - I create product category. -- - !record {model: product.category, id: product_category_allproductssellable0}: - name: Mobile Products Sellable -- - I create partner. -- - !record {model: res.partner, id: res_partner_microlinktechnologies0}: - address: - - street: Kailash Vaibhav, Parksite - name: Micro Link Technologies - property_account_payable: account_pos_account_payable - property_account_receivable: account_pos_account_receivable - supplier: true -- - I create partner address . -- - !record {model: res.partner.address, id: res_partner_address_0}: - country_id: base.in - partner_id: res_partner_microlinktechnologies0 - street: Ash House, Ash Road - title: base.res_partner_title_miss -- - I create product category . -- - !record {model: product.category, id: product_category_services0}: - name: Mobile Services -- - I create product Samsung Mobile. -- - !record {model: product.product, id: product_product_samsungmobile0}: - categ_id: product_category_allproductssellable0 - cost_method: standard - list_price: 170.0 - mes_type: fixed - name: Samsung Mobile - procure_method: make_to_order - property_account_expense: account_pos_account_payable - property_account_income: account_pos_account_receivable - seller_delay: '1' - standard_price: 160.0 - supply_method: produce - type: product - uom_id: product.product_uom_unit - uom_po_id: product.product_uom_unit -- - I create product category . -- - !record {model: product.category, id: product_category_computer0}: - name: Computer -- - I create product HP Pavilion Desktop PCs -- - !record {model: product.product, id: product_product_hppaviliondesktoppcs0}: - categ_id: product_category_computer0 - cost_method: standard - mes_type: fixed - list_price: 1000.0 - name: HP Pavilion Desktop PCs - procure_method: make_to_stock - seller_ids: - - delay: 1 - name: res_partner_microlinktechnologies0 - min_qty: 5.0 - supply_method: buy - type: product - uom_id: product.product_uom_unit - uom_po_id: product.product_uom_unit - property_account_expense: account_pos_account_payable - property_account_income: account_pos_account_receivable -- - I create New Order by adding the details of Salesman and "Product" as Samsung Mobile Quantity as 10. + I create a PoS with 2 PC1 and 3 PC2. - !record {model: pos.order, id: pos_order_pos0}: company_id: base.main_company - date_order: !eval time.strftime('%Y-%m-%d %H:%M:%S') - date_validity: !eval "(datetime.now() + timedelta(6*1)).strftime('%Y-%m-%d')" lines: - - company_id: base.main_company - name: Order Line/01 - notice: No Discount - product_id: product_product_samsungmobile0 - qty: 10.0 - qty_rfd: 0.0 - partner_id: base.res_partner_agrolait - name: POS/001 - price_type: tax_excluded - pricelist_id: product.list0 - sale_journal: account.sales_journal - shop_id: sale.shop - user_salesman_id: base.user_root + - name: OL/0001 + product_id: product.product_product_pc1 + price_unit: 450 + discount: 0.0 + qty: 2.0 + - name: OL/0002 + product_id: product.product_product_pc2 + price_unit: 300 + discount: 0.0 + qty: 3.0 +- + I check that the total of the order is equal to 450 * 2 / 300 * 3 +- + !python {model: pos.order}: | + order = self.browse(cr, uid, ref('pos_order_pos0')) + assert(abs(order.amount_total - 1800.0) < 0.01), "The order has a wrong amount" - - I add discount. + I want to add a global discount of 5 percent using the wizard - !record {model: pos.discount, id: pos_discount_0}: discount: 5.0 - discount_notes: More then 5 product - - I Apply the discount. + I click the apply button to set the discount on all lines - !python {model: pos.discount}: | - self.apply_discount(cr, uid, [ref("pos_discount_0")], {"lang": "en_US", "active_model": - "pos.order", "active_ids": [ref("pos_order_pos0")], "tz": False, "active_id": - ref("pos_order_pos0"), }) -- - I open the register. -- - !record {model: pos.open.statement, id: pos_open_statement_0}: - {} -- - I open the statement. -- - !python {model: pos.open.statement}: | - jou_obj = self.pool.get('account.journal') - statement_obj = self.pool.get('account.bank.statement') - cr.execute("SELECT DISTINCT journal_id FROM pos_journal_users " - "WHERE user_id = %s ORDER BY journal_id"% (uid, )) - jou_ids = map(lambda x1: x1[0], cr.fetchall()) - journal_ids = jou_obj.search(cr, uid, [('auto_cash', '=', True), ('type', '=', 'cash'), ('id', 'in', jou_ids)], context=context) - ids = statement_obj.search(cr, uid, [('state', '=', 'open'), ('user_id', '=', uid), ('journal_id', 'in', journal_ids)], context=context) - if not ids: - self.open_statement(cr, uid, [ref("pos_open_statement_0")], {"lang": "en_US", "active_model": - "ir.ui.menu", "active_ids": [ref("point_of_sale.menu_open_statement")], "tz": - False, "active_id": ref("point_of_sale.menu_open_statement"), }) -- - I click on the "Make Payment" wizard. -- - !record {model: pos.make.payment, id: pos_make_payment_0}: - amount: 1615.0 - journal: 7 - payment_date: !eval time.strftime("%Y-%m-%d") - payment_name: Payment - product_id: product_product_hppaviliondesktoppcs0 - pricelist_id: product.list0 - partner_id: base.res_partner_agrolait -- - I make the payment. -- - !python {model: pos.make.payment}: | - self.check(cr, uid, [ref("pos_make_payment_0")], {"lang": "en_US", "active_model": - "pos.order", "active_ids": [ref("point_of_sale.pos_order_pos0")], "tz": - False, "active_id": ref("point_of_sale.pos_order_pos0"), }) -- - I check the Statement lines are created automatically when payment is done. -- - !python {model: pos.order}: | - order=self.browse(cr,uid,ref("pos_order_pos0")) - assert(order.statement_ids!=[]), "Statement lines not created" -- - When I click on Return picking button , I get three option. -- - 1. Cancel 2.Return Goods and Exchange 3.Return without Refund -- - When I click on Return Goods and Exchange. -- - Then it allows me to define the quantity of products, which will return to the stock. -- - I click on Return Picking button. -- - !record {model: pos.return, id: pos_return_0}: - pos_moves_ids: - - product_id: product_product_hppaviliondesktoppcs0 - quantity: 5.0 -- - I Return the product. -- - !python {model: pos.return}: | - self.create_returns(cr, uid, [ref("pos_return_0")], {"lang": "en_US", "active_model": - "pos.order", "active_ids": [ref("point_of_sale.pos_order_pos0")], "tz": - False, "active_id": ref("point_of_sale.pos_order_pos0"), }) -- - Then it allows me to define the quantity of products, which will return to the stock. -- - I select the HP Pavilion Desktop PCs for exchange. -- - !record {model: pos.add.product, id: pos_add_product_0}: - product_id: product_product_hppaviliondesktoppcs0 - quantity: 5.0 -- - I click on close button. -- - !python {model: pos.add.product}: | - return_obj = self.pool.get('pos.return') - context['active_ids'] = [ref("pos_order_pos0")] - return_obj.view_init(cr, uid, [],context=context) - self.close_action(cr, uid, [ref("pos_add_product_0")], {"lang": "en_US", "active_model": - "pos.order", "active_ids": [ref("pos_order_pos0")], "tz": False, "active_id": ref("pos_order_pos0"), - }) -- - I create payment. -- - !record {model: pos.make.payment, id: pos_make_payment_1}: - amount: 680.0 - journal: 7 - payment_date: !eval time.strftime("%Y-%m-%d") - payment_name: Payment - product_id: product_product_hppaviliondesktoppcs0 - pricelist_id: product.list0 - partner_id: base.res_partner_agrolait -- - For payment, I click on Make Payment. -- - !python {model: pos.make.payment}: | - self.check(cr, uid, [ref("pos_make_payment_1")], {"lang": "en_US", "active_model": - "pos.order", "active_ids": [ref("pos_order_pos0")], "tz": - False, "active_id": ref("pos_order_pos0"), }) -- - To check the Return without Refund . I click button "Return without Refund ". -- - !record {model: pos.return, id: pos_return_0}: - {} -- - The quantity which is selected in Return lines wizard is refunded. -- - !python {model: pos.return}: | - self.create_returns2(cr, uid, [ref("pos_return_0")], {"lang": "en_US", "active_model": - "pos.order", "active_ids": [ref("pos_order_pos0")], "tz": - False, "active_id": ref("pos_order_pos0"), }) -- - To Close order, I use the wizard "Sale Confirm". -- - !record {model: pos.confirm, id: pos_confirm_0}: - {} -- - I close this order. -- - !python {model: pos.confirm}: | - self.action_confirm(cr, uid, [ref("pos_confirm_0")], {"lang": "en_US", "active_model": - "pos.order", "active_ids": [ref("pos_order_pos0")], "tz": False, "active_id": ref("pos_order_pos0"), - }) + self.apply_discount(cr, uid, [ref("pos_discount_0")], {"active_model": "pos.order", + "active_ids": [ref("pos_order_pos0")], "active_id": ref("pos_order_pos0"), }) - - I check order state is done. + I check that the total of the order is not equal to (450 * 2 / 300 * 3)*0.95 - !python {model: pos.order}: | - order=self.browse(cr,uid,ref("pos_order_pos0")) - assert(order.state=='done'), "Order is not done" + order = self.browse(cr, uid, ref('pos_order_pos0')) + assert(abs(order.amount_total - (450*2+300*3)*0.95) < 0.01), "The order has a wrong amount" +#- +# I open the register. +#- +# !record {model: pos.open.statement, id: pos_open_statement_0}: +# {} +#- +# I open the statement. +#- +# !python {model: pos.open.statement}: | +# jou_obj = self.pool.get('account.journal') +# statement_obj = self.pool.get('account.bank.statement') +# cr.execute("SELECT DISTINCT journal_id FROM pos_journal_users " +# "WHERE user_id = %s ORDER BY journal_id"% (uid, )) +# jou_ids = map(lambda x1: x1[0], cr.fetchall()) +# journal_ids = jou_obj.search(cr, uid, [('auto_cash', '=', True), ('type', '=', 'cash'), ('id', 'in', jou_ids)], context=context) +# ids = statement_obj.search(cr, uid, [('state', '=', 'open'), ('user_id', '=', uid), ('journal_id', 'in', journal_ids)], context=context) +# if not ids: +# self.open_statement(cr, uid, [ref("pos_open_statement_0")], {"lang": "en_US", "active_model": +# "ir.ui.menu", "active_ids": [ref("point_of_sale.menu_open_statement")], "tz": +# False, "active_id": ref("point_of_sale.menu_open_statement"), }) +#- +# I click on the "Make Payment" wizard. +#- +# !record {model: pos.make.payment, id: pos_make_payment_0}: +# amount: 1615.0 +# journal: 7 +# payment_date: !eval time.strftime("%Y-%m-%d") +# payment_name: Payment +# product_id: product_product_hppaviliondesktoppcs0 +# pricelist_id: product.list0 +# partner_id: base.res_partner_agrolait +#- +# I make the payment. +#- +# !python {model: pos.make.payment}: | +# self.check(cr, uid, [ref("pos_make_payment_0")], {"lang": "en_US", "active_model": +# "pos.order", "active_ids": [ref("point_of_sale.pos_order_pos0")], "tz": +# False, "active_id": ref("point_of_sale.pos_order_pos0"), }) +#- +# I check the Statement lines are created automatically when payment is done. +#- +# !python {model: pos.order}: | +# order=self.browse(cr,uid,ref("pos_order_pos0")) +# assert(order.statement_ids!=[]), "Statement lines not created" +#- +# When I click on Return picking button , I get three option. +#- +# 1. Cancel 2.Return Goods and Exchange 3.Return without Refund +#- +# When I click on Return Goods and Exchange. +#- +# Then it allows me to define the quantity of products, which will return to the stock. +#- +# I click on Return Picking button. +#- +# !record {model: pos.return, id: pos_return_0}: +# pos_moves_ids: +# - product_id: product_product_hppaviliondesktoppcs0 +# quantity: 5.0 +#- +# I Return the product. +#- +# !python {model: pos.return}: | +# self.create_returns(cr, uid, [ref("pos_return_0")], {"lang": "en_US", "active_model": +# "pos.order", "active_ids": [ref("point_of_sale.pos_order_pos0")], "tz": +# False, "active_id": ref("point_of_sale.pos_order_pos0"), }) +#- +# Then it allows me to define the quantity of products, which will return to the stock. +#- +# I select the HP Pavilion Desktop PCs for exchange. +#- +# !record {model: pos.add.product, id: pos_add_product_0}: +# product_id: product_product_hppaviliondesktoppcs0 +# quantity: 5.0 +#- +# I click on close button. +#- +# !python {model: pos.add.product}: | +# return_obj = self.pool.get('pos.return') +# context['active_ids'] = [ref("pos_order_pos0")] +# return_obj.view_init(cr, uid, [],context=context) +# self.close_action(cr, uid, [ref("pos_add_product_0")], {"lang": "en_US", "active_model": +# "pos.order", "active_ids": [ref("pos_order_pos0")], "tz": False, "active_id": ref("pos_order_pos0"), +# }) +#- +# I create payment. +#- +# !record {model: pos.make.payment, id: pos_make_payment_1}: +# amount: 680.0 +# journal: 7 +# payment_date: !eval time.strftime("%Y-%m-%d") +# payment_name: Payment +# product_id: product_product_hppaviliondesktoppcs0 +# pricelist_id: product.list0 +# partner_id: base.res_partner_agrolait +#- +# For payment, I click on Make Payment. +#- +# !python {model: pos.make.payment}: | +# self.check(cr, uid, [ref("pos_make_payment_1")], {"lang": "en_US", "active_model": +# "pos.order", "active_ids": [ref("pos_order_pos0")], "tz": +# False, "active_id": ref("pos_order_pos0"), }) +#- +# To check the Return without Refund . I click button "Return without Refund ". +#- +# !record {model: pos.return, id: pos_return_0}: +# {} +#- +# The quantity which is selected in Return lines wizard is refunded. +#- +# !python {model: pos.return}: | +# self.create_returns2(cr, uid, [ref("pos_return_0")], {"lang": "en_US", "active_model": +# "pos.order", "active_ids": [ref("pos_order_pos0")], "tz": +# False, "active_id": ref("pos_order_pos0"), }) +#- +# To Close order, I use the wizard "Sale Confirm". +#- +# !record {model: pos.confirm, id: pos_confirm_0}: +# {} +#- +# I close this order. +#- +# !python {model: pos.confirm}: | +# self.action_confirm(cr, uid, [ref("pos_confirm_0")], {"lang": "en_US", "active_model": +# "pos.order", "active_ids": [ref("pos_order_pos0")], "tz": False, "active_id": ref("pos_order_pos0"), +# }) +#- +# I check order state is done. +#- +# !python {model: pos.order}: | +# order=self.browse(cr,uid,ref("pos_order_pos0")) +# assert(order.state=='done'), "Order is not done" diff --git a/addons/point_of_sale/wizard/__init__.py b/addons/point_of_sale/wizard/__init__.py index 4a131d5894bf..1c95aa17ab08 100644 --- a/addons/point_of_sale/wizard/__init__.py +++ b/addons/point_of_sale/wizard/__init__.py @@ -19,7 +19,6 @@ # ############################################################################## -import pos_add_product import pos_confirm import pos_discount import pos_get_sale @@ -37,8 +36,6 @@ import pos_payment_report_user import pos_payment_report_date import pos_payment_report import pos_payment -import pos_scan_product -import pos_return # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_add_product.py b/addons/point_of_sale/wizard/pos_add_product.py deleted file mode 100644 index dfbb96a45140..000000000000 --- a/addons/point_of_sale/wizard/pos_add_product.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -from osv import osv, fields -from tools.translate import _ - - -class add_product(osv.osv_memory): - _name = 'pos.add.product' - _description = 'Add Product' - - _columns = { - 'product_id': fields.many2one('product.product', 'Product', required=True), - 'quantity': fields.float('Quantity', required=True), - } - _defaults = { - 'quantity': 1, - } - - def select_product(self, cr, uid, ids, context=None): - """ - To get the product and quantity and add in order . - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param context: A standard dictionary - @return : Return the add product form again for adding more product - """ - if context is None: - context = {} - this = self.browse(cr, uid, ids[0], context=context) - record_id = context and context.get('active_id', False) - assert record_id, _('Active ID is not found') - if record_id: - order_obj = self.pool.get('pos.order') - order_obj.add_product(cr, uid, record_id, this.product_id.id, this.quantity, context=context) - return { - 'name': _('Add Product'), - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'pos.add.product', - 'view_id': False, - 'target': 'new', - 'views': False, - 'type': 'ir.actions.act_window', - } - - def close_action(self, cr, uid, ids, context=None): - """ - To get the product and Make the payment . - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param context: A standard dictionary - @return : Return the Make Payment - """ - if context is None: - context = {} - record_id = context and context.get('active_id', False) - order_obj= self.pool.get('pos.order') - this = self.browse(cr, uid, ids[0], context) - order_obj.add_product(cr, uid, record_id, this.product_id.id, this.quantity, context=context) - - order_obj.write(cr, uid, [record_id], {'state': 'done'}, context=context) - return { - 'name': _('Make Payment'), - 'context': context and context.get('active_id', False), - 'view_type': 'form', - 'view_mode': 'form', - 'res_model': 'pos.make.payment', - 'view_id': False, - 'target': 'new', - 'views': False, - 'type': 'ir.actions.act_window', - } - -add_product() - -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/point_of_sale/wizard/pos_add_product.xml b/addons/point_of_sale/wizard/pos_add_product.xml deleted file mode 100644 index ac5fd1c6f65d..000000000000 --- a/addons/point_of_sale/wizard/pos_add_product.xml +++ /dev/null @@ -1,41 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<openerp> - <data> - <!-- Add Product --> - - <record id="view_add_product" model="ir.ui.view"> - <field name="name">Add Product</field> - <field name="model">pos.add.product</field> - <field name="type">form</field> - <field name="arch" type="xml"> - <form string="Add product :"> - <group col="6" colspan="4"> - <field name="product_id"/> - <field name="quantity"/> - <separator string="" colspan="4"/> - <newline/> - <group colspan="4" col="4"> - <label string="" colspan="1"/> - <button icon="gtk-stop" special="cancel" - string="Cancel"/> - <button icon="gtk-ok" name="close_action" - string="Save & Close" type="object"/> - <button name="select_product" string="Save & New" - colspan="1" type="object" icon="gtk-add"/> - </group> - </group> - </form> - </field> - </record> - - <record id="action_add_product" model="ir.actions.act_window"> - <field name="name">Add Product</field> - <field name="type">ir.actions.act_window</field> - <field name="res_model">pos.add.product</field> - <field name="view_type">form</field> - <field name="view_mode">form</field> - <field name="target">new</field> - </record> - - </data> -</openerp> diff --git a/addons/point_of_sale/wizard/pos_box_out.py b/addons/point_of_sale/wizard/pos_box_out.py index 74f1a968bc75..e24dcb744b97 100644 --- a/addons/point_of_sale/wizard/pos_box_out.py +++ b/addons/point_of_sale/wizard/pos_box_out.py @@ -84,15 +84,6 @@ class pos_box_out(osv.osv_memory): address_u = res_obj.browse(cr, uid, uid, context=context).address_id am = 0.0 product = product_obj.browse(cr, uid, data['product_id'], context=context) - amount_check = product.am_out or False - for st in stat_done: - for s in st.line_ids: - if address_u and s.partner_id == address_u.partner_id and s.am_out: - am += s.amount - if (-data['amount'] or 0.0) + am < -(res_obj.browse(cr, uid, uid, context=context).company_id.max_diff or 0.0) and amount_check: - val = (res_obj.browse(cr, uid, uid).company_id.max_diff or 0.0) + am - raise osv.except_osv(_('Error !'), _('The maximum value you can still withdraw is exceeded. \n Remaining value is equal to %d ')%(val)) - acc_id = product.property_account_income if not acc_id: raise osv.except_osv(_('Error !'), _('please check that account is set to %s')%(product.name)) @@ -115,8 +106,6 @@ class pos_box_out(osv.osv_memory): if data['amount'] > 0: amount = -data['amount'] vals['amount'] = amount - if product.am_out: - vals['am_out'] = True vals['ref'] = data['ref'] or '' vals['name'] = "%s: %s " % (product.name, data['name']) address_u = res_obj.browse(cr, uid, uid, context=context).address_id diff --git a/addons/point_of_sale/wizard/pos_discount.py b/addons/point_of_sale/wizard/pos_discount.py index 928fe396f0bd..aadd85b48eb3 100644 --- a/addons/point_of_sale/wizard/pos_discount.py +++ b/addons/point_of_sale/wizard/pos_discount.py @@ -23,34 +23,28 @@ from osv import osv, fields class pos_discount(osv.osv_memory): _name = 'pos.discount' - _description = 'Add Discount' - + _description = 'Add a Global Discount' _columns = { - 'discount': fields.float('Discount ', required=True), - 'discount_notes': fields.char('Discount Notes', size= 128, required=True), + 'discount': fields.float('Discount (%)', required=True, digits=(16,2)), } _defaults = { 'discount': 5, } - - def view_init(self, cr, uid, fields_list, context=None): - """ - Creates view dynamically and adding fields at runtime. - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param context: A standard dictionary - @return: New arch of view with new columns. - """ - if context is None: - context = {} - super(pos_discount, self).view_init(cr, uid, fields_list, context=context) - record_id = context and context.get('active_id', False) or False - order = self.pool.get('pos.order').browse(cr, uid, record_id, context=context) - if not order.lines: - raise osv.except_osv(_('Error!'), _('No Order Lines')) - True +# def view_init(self, cr, uid, fields_list, context=None): +# """ +# Creates view dynamically and adding fields at runtime. +# @param self: The object pointer. +# @param cr: A database cursor +# @param uid: ID of the user currently logged in +# @param context: A standard dictionary +# @return: New arch of view with new columns. +# """ +# if context is None: +# context = {} +# super(pos_discount, self).view_init(cr, uid, fields_list, context=context) +# record_id = context and context.get('active_id', False) or False +# True def apply_discount(self, cr, uid, ids, context=None): """ @@ -70,33 +64,8 @@ class pos_discount(osv.osv_memory): record_id = context and context.get('active_id', False) if isinstance(record_id, (int, long)): record_id = [record_id] - for order in order_ref.browse(cr, uid, record_id, context=context): - for line in order.lines: - company_discount = order.company_id.company_discount - applied_discount = this.discount - - if applied_discount == 0.00: - notice = 'No Discount' - elif company_discount >= applied_discount: - notice = 'Minimum Discount' - else: - notice = this.discount_notes - res_new = {} - if this.discount <= company_discount: - res_new = { - 'discount': this.discount, - 'notice': notice, - 'price_ded': line.price_unit * line.qty * (this.discount or 0) * 0.01 or 0.0 - } - else: - res_new = { - 'discount': this.discount, - 'notice': notice, - 'price_ded': line.price_unit * line.qty * (this.discount or 0) * 0.01 or 0.0 - } - - order_line_ref.write(cr, uid, [line.id], res_new, context=context) + order_line_ref.write(cr, uid, [x.id for x in order.lines], {'discount':this.discount}, context=context) return {} pos_discount() diff --git a/addons/point_of_sale/wizard/pos_discount.xml b/addons/point_of_sale/wizard/pos_discount.xml index a0a7c534a95e..0602d5f803e0 100644 --- a/addons/point_of_sale/wizard/pos_discount.xml +++ b/addons/point_of_sale/wizard/pos_discount.xml @@ -1,22 +1,21 @@ <?xml version="1.0" encoding="utf-8"?> <openerp> - <data> + <data> <!-- Add Product --> - - <record id="view_pos_discount" model="ir.ui.view"> + + <record id="view_pos_discount" model="ir.ui.view"> <field name="name">Apply Discount</field> <field name="model">pos.discount</field> <field name="type">form</field> <field name="arch" type="xml"> <form string="Apply Discount"> - <group col="2" colspan="4"> - <field name="discount"/> - <field name="discount_notes"/> - <button icon='gtk-cancel' special="cancel" - string="Close" /> - <button name="apply_discount" string="Apply Discount" - colspan="1" type="object" icon="gtk-ok" /> - </group> + <group col="2" colspan="4"> + <field name="discount"/> + <button icon='gtk-cancel' special="cancel" + string="Close" /> + <button name="apply_discount" string="Apply Discount" + colspan="1" type="object" icon="gtk-ok" /> + </group> </form> </field> </record> @@ -29,6 +28,6 @@ <field name="view_mode">form</field> <field name="target">new</field> </record> - - </data> -</openerp> \ No newline at end of file + + </data> +</openerp> diff --git a/addons/point_of_sale/wizard/pos_payment.py b/addons/point_of_sale/wizard/pos_payment.py index ea5bd2639d7f..251c847586e9 100644 --- a/addons/point_of_sale/wizard/pos_payment.py +++ b/addons/point_of_sale/wizard/pos_payment.py @@ -29,188 +29,43 @@ import pos_box_entries class pos_make_payment(osv.osv_memory): _name = 'pos.make.payment' _description = 'Point of Sale Payment' - - def default_get(self, cr, uid, fields, context=None): - """ - To get default values for the object. - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param fields: List of fields for which we want default values - @param context: A standard dictionary - @return: A dictionary which of fields with values. - """ - if context is None: - context = {} - journal_obj = self.pool.get('account.journal') - order_obj = self.pool.get('pos.order') - res = super(pos_make_payment, self).default_get(cr, uid, fields, context=context) - active_id = context and context.get('active_id', False) - if active_id: - cr.execute("SELECT DISTINCT journal_id FROM pos_journal_users " - "WHERE user_id = %d ORDER BY journal_id"% (uid, )) - j_ids = map(lambda x1: x1[0], cr.fetchall()) - journal = journal_obj.search(cr, uid, [('type', '=', 'cash'), ('id', 'in', j_ids)], context=context) - journal = journal and journal[0] or False - order = order_obj.browse(cr, uid, active_id, context=context) - #get amount to pay - amount = order.amount_total - order.amount_paid - if amount <= 0.0: - context.update({'flag': True}) - order_obj.action_paid(cr, uid, [active_id], context) - elif order.amount_paid > 0.0: - order_obj.write(cr, uid, [active_id], {'state': 'advance'}, context=context) - invoice_wanted_checked = False - - current_date = time.strftime('%Y-%m-%d') - - if 'journal' in fields: - res.update({'journal': journal}) - if 'amount' in fields: - res.update({'amount': amount}) - if 'invoice_wanted' in fields: - res.update({'invoice_wanted': invoice_wanted_checked}) - if 'payment_date' in fields: - res.update({'payment_date': current_date}) - if 'payment_name' in fields: - res.update({'payment_name': 'Payment'}) - if 'partner_id' in fields: - res.update({'partner_id': order.partner_id.id or False}) - if 'pricelist_id' in fields: - res.update({'pricelist_id': order.pricelist_id.id or False}) - return res - - def view_init(self, cr, uid, fields_list, context=None): - if context is None: - context = {} - super(pos_make_payment, self).view_init(cr, uid, fields_list, context=context) - active_id = context and context.get('active_id', False) or False - if active_id: - order = self.pool.get('pos.order').browse(cr, uid, active_id, context=context) - if not order.lines: - raise osv.except_osv(_('Error!'),_('No order lines defined for this sale ')) - return True - - def fields_view_get(self, cr, uid, view_id=None, view_type='form', context=None, toolbar=False, submenu=False): - """ - Changes the view dynamically - - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param context: A standard dictionary - - @return: New arch of view. - - """ - result = super(pos_make_payment, self).fields_view_get(cr, uid, view_id=view_id, view_type=view_type, context=context, toolbar=toolbar,submenu=False) - if context is None: - context = {} - active_model = context.get('active_model') - active_id = context and context.get('active_id', False) or False - if not active_id or (active_model and active_model != 'pos.order'): - return result - - order = self.pool.get('pos.order').browse(cr, uid, active_id, context=context) - if order.amount_total == order.amount_paid: - result['arch'] = """ <form string="Make Payment" colspan="4"> - <group col="2" colspan="2"> - <label string="Do you want to print the Receipt?" colspan="4"/> - <separator colspan="4"/> - <button icon="gtk-cancel" special="cancel" string="No" readonly="0"/> - <button name="print_report" string="Print Receipt" type="object" icon="gtk-print"/> - </group> - </form> - """ - return result - - def onchange_product_id(self, cr, uid, ids, product_id, amount): - """ Changes amount if product_id changes. - @param product_id: Changed product_id - @param amount: Amount to be paid - @return: Dictionary of changed values - """ - prod_obj = self.pool.get('product.product') - if product_id: - product = prod_obj.browse(cr, uid, product_id) - amount = product.list_price - return {'value': {'amount': amount}} - def check(self, cr, uid, ids, context=None): """Check the order: if the order is not paid: continue payment, - if the order is paid print invoice (if wanted) or ticket. + if the order is paid print ticket. """ + print ids, context + context = context or {} order_obj = self.pool.get('pos.order') obj_partner = self.pool.get('res.partner') - if context is None: - context = {} active_id = context and context.get('active_id', False) + order = order_obj.browse(cr, uid, active_id, context=context) amount = order.amount_total - order.amount_paid - data = self.read(cr, uid, ids, context=context)[0] - for m2o_field in ['product_id','pricelist_id','partner_id']: - data[m2o_field] = data.get(m2o_field, False) and data[m2o_field][0] or False - if data['is_acc']: - amount = self.pool.get('product.product').browse(cr, uid, data['product_id'], context=context).list_price + data = self.read(cr, uid, ids, context=context)[0] if amount != 0.0: - order_obj.write(cr, uid, [active_id], {'invoice_wanted': data['invoice_wanted'], 'partner_id': data['partner_id']}, context=context) order_obj.add_payment(cr, uid, active_id, data, context=context) if order_obj.test_paid(cr, uid, [active_id]): - if data['partner_id'] and data['invoice_wanted']: - partner = obj_partner.browse(cr, uid, data['partner_id'], context=context) - if not partner.address: - raise osv.except_osv(_('Error!'),_("Customer doesn't have an address to make the invoice")) - order_obj.action_invoice(cr, uid, [active_id], context=context) - order_obj.create_picking(cr, uid, [active_id], context=context) - if context.get('return', False): - order_obj.write(cr, uid, [active_id], {'state':'done'}, context=context) - else: - order_obj.write(cr, uid, [active_id],{'state':'paid'}, context=context) - return self.create_invoice(cr, uid, ids, context=context) - else: - context.update({'flag': True}) - order_obj.action_paid(cr, uid, [active_id], context=context) - if context.get('return', False): - order_obj.write(cr, uid, [active_id], {'state':'done'}, context=context) - else: - order_obj.write(cr, uid, [active_id], {'state':'paid'}, context=context) - return self.print_report(cr, uid, ids, context=context) - - context.update({'flag': True}) - # Todo need to check - order_obj.action_paid(cr, uid, [active_id], context=context) - order_obj.write(cr, uid, [active_id], {'state': 'advance'}, context=context) - return self.print_report(cr, uid, ids, context=context) + order_obj.action_paid(cr, uid, [active_id], context=context) + return self.print_report(cr, uid, ids, context=context) + return self.launch_payment(cr, uid, ids, context=context) - def create_invoice(self, cr, uid, ids, context=None): - """ - Create a invoice - """ - if context is None: - context = {} - active_ids = [context and context.get('active_id', False)] - datas = {'ids': active_ids} + def launch_payment(self, cr, uid, ids, context=None): return { - 'type' : 'ir.actions.report.xml', - 'report_name':'pos.invoice', - 'datas' : datas, + 'name': _('Paiement'), + 'view_type': 'form', + 'view_mode': 'form', + 'res_model': 'pos.make.payment', + 'view_id': False, + 'target': 'new', + 'views': False, + 'type': 'ir.actions.act_window', } def print_report(self, cr, uid, ids, context=None): - """ - @summary: To get the date and print the report - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param context: A standard dictionary - @return : retrun report - """ - if context is None: - context = {} active_id = context.get('active_id', []) datas = {'ids' : [active_id]} return { @@ -219,19 +74,25 @@ class pos_make_payment(osv.osv_memory): 'datas': datas, } + def _default_amount(self, cr, uid, context=None): + order_obj = self.pool.get('pos.order') + active_id = context and context.get('active_id', False) + if active_id: + order = order_obj.browse(cr, uid, active_id, context=context) + return order.amount_total - order.amount_paid + return False + _columns = { - 'journal': fields.selection(pos_box_entries.get_journal, "Cash Register", required=True), - 'product_id': fields.many2one('product.product', "Advance"), + 'journal': fields.selection(pos_box_entries.get_journal, "Payment Mode", required=True), 'amount': fields.float('Amount', digits=(16,2), required= True), - 'payment_name': fields.char('Payment name', size=32, required=True), - 'payment_date': fields.date('Payment date', required=True), - 'is_acc': fields.boolean('Advance'), - 'invoice_wanted': fields.boolean('Invoice'), - 'num_sale': fields.char('Num.File', size=32), - 'pricelist_id': fields.many2one('product.pricelist', 'Pricelist'), - 'partner_id': fields.many2one('res.partner', 'Customer'), + 'payment_name': fields.char('Payment Reference', size=32, required=True), + 'payment_date': fields.date('Payment Date', required=True), + } + _defaults = { + 'payment_date': time.strftime('%Y-%m-%d %H:%M:%S'), + 'payment_name': _('Payment'), + 'amount': _default_amount } pos_make_payment() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: diff --git a/addons/point_of_sale/wizard/pos_payment.xml b/addons/point_of_sale/wizard/pos_payment.xml index a6757be6b78a..212c0d8c412b 100644 --- a/addons/point_of_sale/wizard/pos_payment.xml +++ b/addons/point_of_sale/wizard/pos_payment.xml @@ -2,57 +2,37 @@ <openerp> <data> - <!-- Select an Open Sale Order --> - - <record id="view_pos_payment" model="ir.ui.view"> + <record id="view_pos_payment" model="ir.ui.view"> <field name="name">Add payment :</field> <field name="model">pos.make.payment</field> <field name="type">form</field> <field name="arch" type="xml"> - <form string="Add payment :"> - <group colspan="6" col="6" > - <group colspan="3" > - <separator string="The cash register must be opened to be able to execute a payment." /> - </group> - <newline/> - <group colspan="6"> - <field name="journal"/> - <field name="payment_date"/> - <field name="num_sale" /> - <field name="amount" /> - <!--field name="payment_name" /--> - <field name="invoice_wanted" /> - <field name="is_acc" /> - </group> - <group attrs="{'invisible':[('is_acc','=',False)]}" colspan="3" > - <field name="product_id" attrs="{'required':[('is_acc', '=', True)]}" domain="[('type','=','service')]" on_change="onchange_product_id(product_id, amount)"/> - </group> - <newline/> - <group attrs="{'invisible':[('invoice_wanted','=',False)]}" colspan="3"> - <field name="partner_id" attrs="{'required':[('invoice_wanted', '=', True)]}" colspan="2"/> - <field name="pricelist_id" attrs="{'required':[('invoice_wanted', '=', True)]}" colspan="2"/> - </group> - <separator colspan="6"/> - <group colspan="3"/> - <group colspan="3"> - <group colspan="2"/> - <group colspan="2"> - <button icon="gtk-stop" special="cancel" string="Cancel"/> - <button name="check" string="Make Payment" colspan="1" type="object" icon="terp-dolar"/> - </group> - </group> - </group> - </form> + <form string="Add payment :"> + <group colspan="4" col="4" > + <group colspan="4"> + <field name="journal"/> + <field name="amount" /> + <field name="payment_name" groups="base.group_extended"/> + </group> + <newline/> + <separator colspan="4"/> + <group colspan="2"/> + <group colspan="2"> + <button icon="gtk-stop" special="cancel" string="Cancel"/> + <button name="check" string="Make Payment" colspan="1" type="object" icon="gtk-apply"/> + </group> + </group> + </form> </field> </record> <record id="action_pos_payment" model="ir.actions.act_window"> - <field name="name">Add payment</field> + <field name="name">Payment</field> <field name="type">ir.actions.act_window</field> <field name="res_model">pos.make.payment</field> <field name="view_type">form</field> <field name="view_mode">form</field> <field name="target">new</field> </record> - </data> + </data> </openerp> diff --git a/addons/point_of_sale/wizard/pos_return.py b/addons/point_of_sale/wizard/pos_return.py index 24af966cb1c0..a7678cc49657 100644 --- a/addons/point_of_sale/wizard/pos_return.py +++ b/addons/point_of_sale/wizard/pos_return.py @@ -24,19 +24,6 @@ from osv import osv,fields from tools.translate import _ import time -class pos_return_memory(osv.osv_memory): - _name = "pos.return.memory" - _rec_name = 'product_id' - _columns = { - 'product_id' : fields.many2one('product.product', string="Product", required=True), - 'quantity' : fields.float("Quantity", required=True), - 'pos_moves_id' : fields.many2one('pos.return', string="Move"), - 'line_id': fields.integer('Line Id'), - } - -pos_return_memory() - - class pos_return(osv.osv_memory): _name = 'pos.return' _description = 'Point of sale return' @@ -290,7 +277,6 @@ class add_product(osv.osv_memory): res=cr.fetchone() location_id=res and res[0] or None - order_obj.write(cr,uid,[order_id.id],{'type_rec':'Exchange'}) if order_id.invoice_id: invoice_obj.refund(cr, uid, [order_id.invoice_id.id], time.strftime('%Y-%m-%d'), False, order_id.name) new_picking=picking_obj.create(cr, uid, { @@ -305,7 +291,6 @@ class add_product(osv.osv_memory): if data.has_key(key): qty = data[key] lines_obj.write(cr,uid,[line.id], { - 'qty_rfd':(line.qty or 0.0) + data[key], 'qty':line.qty-(data[key] or 0.0) }) else: diff --git a/addons/point_of_sale/wizard/pos_return_view.xml b/addons/point_of_sale/wizard/pos_return_view.xml index 7509b55b5d82..d89eb8f87455 100644 --- a/addons/point_of_sale/wizard/pos_return_view.xml +++ b/addons/point_of_sale/wizard/pos_return_view.xml @@ -7,15 +7,8 @@ <field name="type">form</field> <field name="arch" type="xml"> <form string="Return lines"> - <label string=" Enter the quantities which you want to return." colspan="4"/> - <separator colspan="4"/> - <field name="pos_moves_ids" colspan="4" nolabel="1" mode="tree,form" width="550" height="200" > - </field> - <newline/> - <separator colspan="4"/> <button icon='gtk-cancel' special="cancel" string="Cancel" /> - <button icon='gtk-ok' name= "create_returns" string="Return With Exchange" type="object"/> - <button icon='gtk-ok' name="create_returns2" string="Refund Without Exchange" type="object"/> + <button icon='gtk-ok' name= "create_returns" string="Return Products" type="object"/> </form> </field> </record> diff --git a/addons/point_of_sale/wizard/pos_scan_product.py b/addons/point_of_sale/wizard/pos_scan_product.py deleted file mode 100644 index 8e1e4aace862..000000000000 --- a/addons/point_of_sale/wizard/pos_scan_product.py +++ /dev/null @@ -1,51 +0,0 @@ -# -*- coding: utf-8 -*- -############################################################################## -# -# OpenERP, Open Source Management Solution -# Copyright (C) 2004-2010 Tiny SPRL (<http://tiny.be>). -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, either version 3 of the -# License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. -# -############################################################################## - -from osv import osv,fields - - -class pos_scan_product(osv.osv_memory): - _name = 'pos.scan.product' - _description = 'Scan product' - - _columns = { - 'gencod': fields.char('Barcode', size=13, required=True) - } - - def scan(self, cr, uid, ids, context=None): - """ - To get the gencod and scan product - @param self: The object pointer. - @param cr: A database cursor - @param uid: ID of the user currently logged in - @param context: A standard dictionary - @return : retrun gencod - """ - if context is None: - context = {} - data=self.read(cr, uid, ids)[0] - record_id = context and context.get('active_id', False) - self. pool.get('pos.order.line')._scan_product(cr, uid, data['gencod'], 1, record_id) - return {'gencod': False} - -pos_scan_product() -# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: - diff --git a/addons/point_of_sale/wizard/pos_scan_product_view.xml b/addons/point_of_sale/wizard/pos_scan_product_view.xml deleted file mode 100644 index 3957c6c04150..000000000000 --- a/addons/point_of_sale/wizard/pos_scan_product_view.xml +++ /dev/null @@ -1,34 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<openerp> - <data> - <record id="view_pos_scan_product" model="ir.ui.view"> - <field name="name">Scan product</field> - <field name="model">pos.scan.product</field> - <field name="type">form</field> - <field name="arch" type="xml"> - <form string="Scan product"> - <group col="2" colspan="4"> - <label string="Scan Barcode" colspan="4"/> - <field name="gencod" colspan="4" nolabel="1"/> - <button icon='gtk-cancel' special="cancel" - string="Close" /> - <button name="scan" string="Add" - colspan="1" type="object" icon="gtk-ok" /> - </group> - </form> - </field> - </record> - - - <record id="action_pos_scan_product" model="ir.actions.act_window"> - <field name="name">Scan product</field> - <field name="type">ir.actions.act_window</field> - <field name="res_model">pos.scan.product</field> - <field name="view_type">form</field> - <field name="view_mode">form</field> - <field name="target">new</field> - - </record> - - </data> -</openerp> \ No newline at end of file -- GitLab