diff --git a/addons/point_of_sale/__openerp__.py b/addons/point_of_sale/__openerp__.py index 7b0a35e9632..70606933913 100644 --- a/addons/point_of_sale/__openerp__.py +++ b/addons/point_of_sale/__openerp__.py @@ -79,6 +79,7 @@ Main features : ], 'test': [ 'test/01_order_to_payment.yml', + 'test/02_order_to_invoice.yml', 'test/point_of_sale_report.yml' ], 'installable': True, diff --git a/addons/point_of_sale/point_of_sale.py b/addons/point_of_sale/point_of_sale.py index 6757fc08336..e6e06afdc89 100644 --- a/addons/point_of_sale/point_of_sale.py +++ b/addons/point_of_sale/point_of_sale.py @@ -94,7 +94,6 @@ class pos_order(osv.osv): default = {} d = { 'state': 'draft', - 'partner_id': False, 'invoice_id': False, 'account_move': False, 'picking_id': False, @@ -371,16 +370,17 @@ class pos_order(osv.osv): inv_line['invoice_line_tax_id'] = ('invoice_line_tax_id' in inv_line)\ and [(6, 0, inv_line['invoice_line_tax_id'])] or [] inv_line_ref.create(cr, uid, inv_line, context=context) + inv_ref.button_reset_taxes(cr, uid, [inv_id], context=context) 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, + res_id = res and res[1] or False return { 'name': _('PoS Invoices'), 'view_type': 'form', 'view_mode': 'form', - 'view_id': [res_id], + 'view_id': res_id, 'res_model': 'account.invoice', 'context': "{'type':'out_invoice'}", 'type': 'ir.actions.act_window', diff --git a/addons/point_of_sale/test/00_register_open.yml b/addons/point_of_sale/test/00_register_open.yml new file mode 100644 index 00000000000..12adb6543c1 --- /dev/null +++ b/addons/point_of_sale/test/00_register_open.yml @@ -0,0 +1,17 @@ +- + In order to test the Point of Sale module, I will open all cash registers through the wizard +- + I go to the window to open the cash registers as admin +- + !record {model: pos.open.statement, id: new_statement_open}: +- + I click on the button to open all statements/cash registers +- + !python {model: pos.open.statement}: | + self.open_statement(cr, uid, [ref('new_statement_open')], context={}) +- + I check that I have some bank statements open for the admin user +- + !python {model: account.bank.statement}: | + ids = self.search(cr, uid, [('state', '=', 'open'), ('user_id', '=', 1)]) + assert (len(ids)>0), 'No statement open for the admin user !' diff --git a/addons/point_of_sale/test/01_order_to_payment.yml b/addons/point_of_sale/test/01_order_to_payment.yml new file mode 100644 index 00000000000..fd8ffbaa3e0 --- /dev/null +++ b/addons/point_of_sale/test/01_order_to_payment.yml @@ -0,0 +1,124 @@ +- | + In order to test the Point of Sale in module, I will do a full flow from the sale to the payment and invoicing. + I will use two products, one with price including a 10% tax, the other one with 5% tax excluded from the price. +- | + I create a VAT tax of 10%, included in the public price +- + !record {model: account.tax, id: account_tax_10_incl}: + name: VAT 10 perc Incl + type: percent + amount: 0.10 + account_paid_id: account.iva + account_collected_id: account.iva + price_include: 1 +- + I assign this 10 percent tax on the PC1 product as a sale tax +- + !record {model: product.product, id: product.product_product_pc1}: + taxes_id: [account_tax_10_incl] +- | + I create a VAT tax of 5%, which is added to the public price +- + !record {model: account.tax, id: account_tax_05_incl}: + name: VAT 05 perc Excl + type: percent + amount: 0.05 + account_paid_id: account.iva + account_collected_id: account.iva + price_include: 0 +- + I assign this 5 percent tax on the PC2 product as a sale tax +- + !record {model: product.product, id: product.product_product_pc2}: + taxes_id: [account_tax_05_incl] +- + I create a PoS order with 2 units of PC1 at 450 EUR (Tax Incl) and 3 units of PC2 at 300 EUR. (Tax Excl) +- + !record {model: pos.order, id: pos_order_pos0}: + company_id: base.main_company + lines: + - 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*1.05 and the tax of the order is equal to 900 -(450 * 2 / 1.1) + 300*0.05*3 +- + !python {model: pos.order}: | + order = self.browse(cr, uid, ref('pos_order_pos0')) + assert(abs(order.amount_total - (450*2 + 300*3*1.05)) < 0.01), "The order has a wrong amount, tax included" + assert(abs(order.amount_tax - (900-(450*2/1.1) + 300*0.05*3)) < 0.01), "The order has a wrong tax amount" +- + I want to add a global discount of 5 percent using the wizard +- + !record {model: pos.discount, id: pos_discount_0}: + discount: 5.0 +- + 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")], {"active_model": "pos.order", + "active_ids": [ref("pos_order_pos0")], "active_id": ref("pos_order_pos0"), }) +- + I check that the total of the order is now equal to (450*2 + 300*3*1.05)*0.95 +- + !python {model: pos.order}: | + order = self.browse(cr, uid, ref('pos_order_pos0')) + assert(abs(order.amount_total - (450*2 + 300*3*1.05)*0.95) < 0.01), "The order has a wrong total including tax and discounts" +- + I click on the "Make Payment" wizard to pay the PoS order with a partial amount of 100.0 EUR +- + !record {model: pos.make.payment, id: pos_make_payment_0, context: {'active_id': ref('pos_order_pos0'), 'active_ids': [ref('pos_order_pos0')]} }: + amount: 100.0 +- + I click on the validate button to register the payment. +- + !python {model: pos.make.payment}: | + self.check(cr, uid, [ref('pos_make_payment_0')], context={'active_id': ref('pos_order_pos0'), 'lang':'en_US', 'active_model': 'pos.order', 'tz': False, 'active_ids': [ref('pos_order_pos0')]} ) +- | + I check that the order is not marked as paid yet +- + !assert {model: pos.order, id: pos_order_pos0}: + - state == 'draft' +- | + On the second payment proposition, I check that it proposes me the remaining balance which is 1790.0 EUR +- + !python {model: pos.make.payment}: | + defs = self.default_get(cr, uid, ['amount'], {'active_id': ref('pos_order_pos0')}) + assert abs(defs['amount'] - ((450*2 + 300*3*1.05)*0.95-100.0)) < 0.01, "The remaining balance is incorrect" +- + I pay the remaining balance. +- + !record {model: pos.make.payment, id: pos_make_payment_1, context: {'active_id': [ref('pos_order_pos0')], 'active_ids': [ref('pos_order_pos0')]} }: + amount: !eval > + (450*2 + 300*3*1.05)*0.95-100.0 +- + I click on the validate button to register the payment. +- + !python {model: pos.make.payment}: | + self.check(cr, uid, [ref('pos_make_payment_1')], context={'active_id': ref('pos_order_pos0')} ) +- | + I check that the order is marked as paid +- + !assert {model: pos.order, id: pos_order_pos0}: + - state == 'paid' +- + I generate the journal entries +- + !python {model: pos.order}: | + self.create_account_move(cr, uid, [ref('pos_order_pos0')], {}) +- + I test that the generated journal entry is attached to the PoS order +- + !assert {model: pos.order, id: pos_order_pos0}: + - bool(account_move) + + + + diff --git a/addons/point_of_sale/test/02_order_to_invoice.yml b/addons/point_of_sale/test/02_order_to_invoice.yml new file mode 100644 index 00000000000..535eab6999b --- /dev/null +++ b/addons/point_of_sale/test/02_order_to_invoice.yml @@ -0,0 +1,48 @@ +- + I create a new PoS order with 2 units of PC1 at 450 EUR (Tax Incl) and 3 units of PC2 at 300 EUR. (Tax Excl) +- + !record {model: pos.order, id: pos_order_pos1}: + company_id: base.main_company + partner_id: base.res_partner_asus + lines: + - name: OL/0001 + product_id: product.product_product_pc1 + price_unit: 450 + discount: 5.0 + qty: 2.0 + - name: OL/0002 + product_id: product.product_product_pc2 + price_unit: 300 + discount: 5.0 + qty: 3.0 +- + I click on the "Make Payment" wizard to pay the PoS order +- + !record {model: pos.make.payment, id: pos_make_payment_2, context: {'active_id': ref('pos_order_pos1'), 'active_ids': [ref('pos_order_pos1')]} }: + amount: !eval > + (450*2 + 300*3*1.05)*0.95 +- + I click on the validate button to register the payment. +- + !python {model: pos.make.payment}: | + self.check(cr, uid, [ref('pos_make_payment_2')], context={'active_id': ref('pos_order_pos1')} ) +- | + I check that the order is marked as paid and there is no invoice attached to it +- + !python {model: pos.order}: | + order = self.browse(cr,uid,ref('pos_order_pos1')) + print order.state, order.invoice_id, order.amount_total, order.amount_paid +- + !assert {model: pos.order, id: pos_order_pos1, string: State not correct}: + - state == 'paid' + - not invoice_id +- + I generate the invoice by pressing the Invoice button that calls the workflow +- + !workflow {model: pos.order, action: invoice, ref: pos_order_pos1} +- + I test that the total of the attached invoice is correct +- + !assert {model: pos.order, id: pos_order_pos1, string: Invoice not correct}: + - bool(invoice_id) + - invoice_id.amount_total == (450*2 + 300*3*1.05)*0.95 diff --git a/addons/point_of_sale/wizard/pos_payment.py b/addons/point_of_sale/wizard/pos_payment.py index 6b2d01d5672..1de3a23614a 100644 --- a/addons/point_of_sale/wizard/pos_payment.py +++ b/addons/point_of_sale/wizard/pos_payment.py @@ -34,7 +34,6 @@ class pos_make_payment(osv.osv_memory): if the order is not paid: continue payment, 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') @@ -43,7 +42,8 @@ class pos_make_payment(osv.osv_memory): 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] - data['journal'] = data['journal'][0] + # this is probably a problem of osv_memory as it's not compatible with normal OSV's + #data['journal'] = data['journal'][0] if amount != 0.0: order_obj.add_payment(cr, uid, active_id, data, context=context) @@ -77,7 +77,7 @@ class pos_make_payment(osv.osv_memory): def _default_journal(self, cr, uid, context=None): res = pos_box_entries.get_journal(self, cr, uid, context=context) - return len(res)>1 and res[1] or False + return len(res)>1 and res[1][0] or False def _default_amount(self, cr, uid, context=None): order_obj = self.pool.get('pos.order')