[TEST] point_of_sale: create one account move by session
We've adapted the tests to work with the new implementation of payments and session closure. And we've added some new ones to have a better coverage on point_of_sale module. TASK-ID: 1862388 closes odoo/odoo#33578 Signed-off-by: pimodoo <pimodoo@users.noreply.github.com>
This commit is contained in:
committed by
Pierre Masereel
parent
b234e97f87
commit
8becb17b8a
@@ -5,3 +5,11 @@ from . import test_point_of_sale_flow
|
||||
from . import test_frontend
|
||||
from . import test_point_of_sale_ui
|
||||
from . import test_anglo_saxon
|
||||
from . import test_pos_setup
|
||||
from . import test_pos_basic_config
|
||||
from . import test_pos_products_with_tax
|
||||
from . import test_pos_multiple_sale_accounts
|
||||
from . import test_pos_multiple_receivable_accounts
|
||||
from . import test_pos_other_currency_config
|
||||
from . import test_pos_with_fiscal_position
|
||||
from . import test_pos_stock_account
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from odoo.tests import common
|
||||
from random import randint
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests.common import TransactionCase, Form
|
||||
from odoo.tools import float_is_zero
|
||||
|
||||
|
||||
class TestPointOfSaleCommon(common.TransactionCase):
|
||||
class TestPointOfSaleCommon(TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPointOfSaleCommon, self).setUp()
|
||||
@@ -11,16 +15,16 @@ class TestPointOfSaleCommon(common.TransactionCase):
|
||||
self.PosMakePayment = self.env['pos.make.payment']
|
||||
self.PosOrder = self.env['pos.order']
|
||||
self.PosSession = self.env['pos.session']
|
||||
company = self.env.ref('base.main_company')
|
||||
self.company_id = company.id
|
||||
self.company = self.env.ref('base.main_company')
|
||||
self.company_id = self.company.id
|
||||
coa = self.env['account.chart.template'].search([
|
||||
('currency_id', '=', company.currency_id.id),
|
||||
('currency_id', '=', self.company.currency_id.id),
|
||||
], limit=1)
|
||||
test_sale_journal = self.env['account.journal'].create({'name': 'Sales Journal - Test',
|
||||
'code': 'TSJ',
|
||||
'type': 'sale',
|
||||
'company_id': self.company_id})
|
||||
company.write({'anglo_saxon_accounting': coa.use_anglo_saxon,
|
||||
self.company.write({'anglo_saxon_accounting': coa.use_anglo_saxon,
|
||||
'bank_account_code_prefix': coa.bank_account_code_prefix,
|
||||
'cash_account_code_prefix': coa.cash_account_code_prefix,
|
||||
'transfer_account_code_prefix': coa.transfer_account_code_prefix,
|
||||
@@ -34,21 +38,19 @@ class TestPointOfSaleCommon(common.TransactionCase):
|
||||
self.pos_config.write({
|
||||
'journal_id': test_sale_journal.id,
|
||||
'invoice_journal_id': test_sale_journal.id,
|
||||
'journal_ids': [(0, 0, {'name': 'Cash Journal - Test',
|
||||
'code': 'TSC',
|
||||
'type': 'cash',
|
||||
'company_id': self.company_id,
|
||||
'journal_user': True})],
|
||||
})
|
||||
})
|
||||
self.led_lamp = self.env.ref('point_of_sale.led_lamp')
|
||||
self.whiteboard_pen = self.env.ref('point_of_sale.whiteboard_pen')
|
||||
self.newspaper_rack = self.env.ref('point_of_sale.newspaper_rack')
|
||||
|
||||
# create a new session
|
||||
self.pos_order_session0 = self.env['pos.session'].create({
|
||||
'user_id': 1,
|
||||
'config_id': self.pos_config.id
|
||||
self.cash_payment_method = self.pos_config.payment_method_ids.filtered(lambda pm: pm.name == 'Cash')
|
||||
self.bank_payment_method = self.pos_config.payment_method_ids.filtered(lambda pm: pm.name == 'Bank')
|
||||
self.credit_payment_method = self.env['pos.payment.method'].create({
|
||||
'name': 'Credit',
|
||||
'receivable_account_id': self.company.account_default_pos_receivable_account_id.id,
|
||||
'split_transactions': True,
|
||||
})
|
||||
self.pos_config.write({'payment_method_ids': [(4, self.credit_payment_method.id)]})
|
||||
|
||||
# create a VAT tax of 10%, included in the public price
|
||||
Tax = self.env['account.tax']
|
||||
@@ -85,3 +87,367 @@ class TestPointOfSaleCommon(common.TransactionCase):
|
||||
# I assign those 5 percent taxes on the PCSC349 product as a sale taxes
|
||||
self.product4.write(
|
||||
{'taxes_id': [(6, 0, [account_tax_05_incl.id, account_tax_05_incl_chicago.id])]})
|
||||
|
||||
# Set account_id in the generated repartition lines. Automatically, nothing is set.
|
||||
invoice_rep_lines = (account_tax_05_incl | account_tax_05_incl_chicago | account_tax_10_incl).mapped('invoice_repartition_line_ids')
|
||||
refund_rep_lines = (account_tax_05_incl | account_tax_05_incl_chicago | account_tax_10_incl).mapped('refund_repartition_line_ids')
|
||||
|
||||
tax_received_account = self.company.account_sale_tax_id.mapped('invoice_repartition_line_ids.account_id')
|
||||
(invoice_rep_lines | refund_rep_lines).write({'account_id': tax_received_account.id})
|
||||
|
||||
|
||||
class TestPoSCommon(TransactionCase):
|
||||
""" Set common values for different special test cases.
|
||||
|
||||
The idea is to set up common values here for the tests
|
||||
and implement different special scenarios by inheriting
|
||||
this class.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestPoSCommon, self).setUp()
|
||||
|
||||
self.pos_manager = self.env.ref('base.user_admin')
|
||||
self.env = self.env(user=self.pos_manager)
|
||||
|
||||
# Set basic defaults
|
||||
self.company = self.env.ref('base.main_company')
|
||||
self.pos_sale_journal = self.env['account.journal'].create({
|
||||
'type': 'sale',
|
||||
'name': 'Point of Sale Test',
|
||||
'code': 'POST',
|
||||
'company_id': self.company.id,
|
||||
'sequence': 20
|
||||
})
|
||||
self.invoice_journal = self.env['account.journal'].create({
|
||||
'type': 'sale',
|
||||
'name': 'Invoice Journal Test',
|
||||
'code': 'INVT',
|
||||
'company_id': self.company.id,
|
||||
'sequence': 21
|
||||
})
|
||||
self.receivable_account = self.pos_manager.partner_id.property_account_receivable_id
|
||||
self.tax_received_account = self.company.account_sale_tax_id.mapped('invoice_repartition_line_ids.account_id')
|
||||
self.pos_receivable_account = self.company.account_default_pos_receivable_account_id
|
||||
self.other_receivable_account = self.env['account.account'].create({
|
||||
'name': 'Other Receivable',
|
||||
'code': 'RCV00' ,
|
||||
'user_type_id': self.env['account.account.type'].create({'name': 'RCV type', 'type': 'receivable'}).id,
|
||||
'reconcile': True,
|
||||
})
|
||||
|
||||
# company_currency can be different from `base.USD` depending on the localization installed
|
||||
self.company_currency = self.company.currency_id
|
||||
# other_currency is a currency different from the company_currency
|
||||
# sometimes company_currency is different from USD, so handle appropriately.
|
||||
self.other_currency = self.env.ref('base.EUR') if self.company_currency == self.env.ref('base.USD') else self.env.ref('base.USD')
|
||||
|
||||
self.currency_pricelist = self.env['product.pricelist'].create({
|
||||
'name': 'Public Pricelist',
|
||||
'currency_id': self.company_currency.id,
|
||||
})
|
||||
# Set Point of Sale configurations
|
||||
# basic_config
|
||||
# - derived from 'point_of_sale.pos_config_main' with added invoice_journal_id and credit payment method.
|
||||
# other_currency_config
|
||||
# - pos.config set to have currency different from company currency.
|
||||
self.basic_config = self._create_basic_config()
|
||||
self.other_currency_config = self._create_other_currency_config()
|
||||
|
||||
# Set product categories
|
||||
# categ_basic
|
||||
# - just the plain 'product.product_category_all'
|
||||
# categ_anglo
|
||||
# - product category with fifo and real_time valuations
|
||||
# - used for checking anglo saxon accounting behavior
|
||||
self.categ_basic = self.env.ref('product.product_category_all')
|
||||
self.categ_anglo = self._create_categ_anglo()
|
||||
|
||||
# other basics
|
||||
self.sale_account = self.categ_basic.property_account_income_categ_id
|
||||
self.other_sale_account = self.env['account.account'].search([
|
||||
('company_id', '=', self.company.id),
|
||||
('user_type_id', '=', self.env.ref('account.data_account_type_revenue').id),
|
||||
('id', '!=', self.sale_account.id)
|
||||
], limit=1)
|
||||
|
||||
# Set customers
|
||||
self.customer = self.env['res.partner'].create({'name': 'Test Customer'})
|
||||
self.other_customer = self.env['res.partner'].create({'name': 'Other Customer', 'property_account_receivable_id': self.other_receivable_account.id})
|
||||
|
||||
# Set taxes
|
||||
# self.taxes => dict
|
||||
# keys: 'tax7', 'tax10'(price_include=True), 'tax_group_7_10'
|
||||
self.taxes = self._create_taxes()
|
||||
|
||||
#####################
|
||||
## private methods ##
|
||||
#####################
|
||||
|
||||
def _create_basic_config(self):
|
||||
new_config = Form(self.env['pos.config'])
|
||||
new_config.name = 'PoS Shop Test'
|
||||
new_config.module_account = True
|
||||
new_config.invoice_journal_id = self.invoice_journal
|
||||
new_config.journal_id = self.pos_sale_journal
|
||||
new_config.available_pricelist_ids.clear()
|
||||
new_config.available_pricelist_ids.add(self.currency_pricelist)
|
||||
new_config.pricelist_id = self.currency_pricelist
|
||||
config = new_config.save()
|
||||
cash_journal = config.payment_method_ids.filtered(lambda pm: pm.is_cash_count)[:1].cash_journal_id
|
||||
cash_split_pm = self.env['pos.payment.method'].create({
|
||||
'name': 'Split (Cash) PM',
|
||||
'receivable_account_id': self.pos_receivable_account.id,
|
||||
'split_transactions': True,
|
||||
'is_cash_count': True,
|
||||
'cash_journal_id': cash_journal.id,
|
||||
})
|
||||
config.write({'payment_method_ids': [(4,cash_split_pm.id,0)]})
|
||||
return config
|
||||
|
||||
def _create_other_currency_config(self):
|
||||
(self.other_currency.rate_ids | self.company_currency.rate_ids).unlink()
|
||||
self.env['res.currency.rate'].create({
|
||||
'rate': 0.5,
|
||||
'currency_id': self.other_currency.id,
|
||||
})
|
||||
other_cash_journal = self.env['account.journal'].create({
|
||||
'name': 'Cash Other',
|
||||
'type': 'cash',
|
||||
'company_id': self.company.id,
|
||||
'code': 'CSHO',
|
||||
'sequence': 10,
|
||||
'currency_id': self.other_currency.id
|
||||
})
|
||||
other_invoice_journal = self.env['account.journal'].create({
|
||||
'name': 'Customer Invoice Other',
|
||||
'type': 'sale',
|
||||
'company_id': self.company.id,
|
||||
'code': 'INVO',
|
||||
'sequence': 11,
|
||||
'currency_id': self.other_currency.id
|
||||
})
|
||||
other_sales_journal = self.env['account.journal'].create({
|
||||
'name':'PoS Sale Other',
|
||||
'type': 'sale',
|
||||
'code': 'POSO',
|
||||
'company_id': self.company.id,
|
||||
'sequence': 12,
|
||||
'currency_id': self.other_currency.id
|
||||
})
|
||||
other_pricelist = self.env['product.pricelist'].create({
|
||||
'name': 'Public Pricelist Other',
|
||||
'currency_id': self.other_currency.id,
|
||||
})
|
||||
other_cash_payment_method = self.env['pos.payment.method'].create({
|
||||
'name': 'Cash Other',
|
||||
'receivable_account_id': self.pos_receivable_account.id,
|
||||
'is_cash_count': True,
|
||||
'cash_journal_id': other_cash_journal.id,
|
||||
})
|
||||
other_bank_payment_method = self.env['pos.payment.method'].create({
|
||||
'name': 'Bank Other',
|
||||
'receivable_account_id': self.pos_receivable_account.id,
|
||||
})
|
||||
|
||||
new_config = Form(self.env['pos.config'])
|
||||
new_config.name = 'Shop Other'
|
||||
new_config.invoice_journal_id = other_invoice_journal
|
||||
new_config.journal_id = other_sales_journal
|
||||
new_config.use_pricelist = True
|
||||
new_config.available_pricelist_ids.clear()
|
||||
new_config.available_pricelist_ids.add(other_pricelist)
|
||||
new_config.pricelist_id = other_pricelist
|
||||
new_config.payment_method_ids.clear()
|
||||
new_config.payment_method_ids.add(other_cash_payment_method)
|
||||
new_config.payment_method_ids.add(other_bank_payment_method)
|
||||
config = new_config.save()
|
||||
return config
|
||||
|
||||
def _create_categ_anglo(self):
|
||||
return self.env['product.category'].create({
|
||||
'name': 'Anglo',
|
||||
'parent_id': False,
|
||||
'property_cost_method': 'fifo',
|
||||
'property_valuation': 'real_time',
|
||||
})
|
||||
|
||||
def _create_taxes(self):
|
||||
""" Create taxes
|
||||
|
||||
tax7: 7%, excluded in product price
|
||||
tax10: 10%, included in product price
|
||||
"""
|
||||
tax7 = self.env['account.tax'].create({'name': 'Tax 7%', 'amount': 7})
|
||||
tax10 = self.env['account.tax'].create({'name': 'Tax 10%', 'amount': 10, 'price_include': True, 'include_base_amount': False})
|
||||
(tax7 | tax10).mapped('invoice_repartition_line_ids').write({'account_id': self.tax_received_account.id})
|
||||
(tax7 | tax10).mapped('refund_repartition_line_ids').write({'account_id': self.tax_received_account.id})
|
||||
|
||||
tax_group_7_10 = tax7.copy()
|
||||
with Form(tax_group_7_10) as tax:
|
||||
tax.name = 'Tax 7+10%'
|
||||
tax.amount_type = 'group'
|
||||
tax.children_tax_ids.add(tax7)
|
||||
tax.children_tax_ids.add(tax10)
|
||||
|
||||
return {
|
||||
'tax7': tax7,
|
||||
'tax10': tax10,
|
||||
'tax_group_7_10': tax_group_7_10
|
||||
}
|
||||
|
||||
####################
|
||||
## public methods ##
|
||||
####################
|
||||
|
||||
def create_random_uid(self):
|
||||
return ('%05d-%03d-%04d' % (randint(1, 99999), randint(1, 999), randint(1, 9999)))
|
||||
|
||||
def create_ui_order_data(self, product_quantity_pairs, customer=False, is_invoiced=False, payments=None, uid=None):
|
||||
""" Mocks the order_data generated by the pos ui.
|
||||
|
||||
This is useful in making orders in an open pos session without making tours.
|
||||
Its functionality is tested in test_pos_create_ui_order_data.py.
|
||||
|
||||
Before use, make sure that self is set with:
|
||||
1. pricelist -> the pricelist of the current session
|
||||
2. currency -> currency of the current session
|
||||
3. pos_session -> the current session, equivalent to config.current_session_id
|
||||
4. cash_pm -> first cash payment method in the current session
|
||||
5. config -> the active pos.config
|
||||
|
||||
The above values should be set when `self.open_new_session` is called.
|
||||
|
||||
:param list(tuple) product_quantity_pairs: pair of `ordered product` and `quantity`
|
||||
:param list(tuple) payments: pair of `payment_method` and `amount`
|
||||
"""
|
||||
default_fiscal_position = self.config.default_fiscal_position_id
|
||||
fiscal_position = customer.property_account_position_id if customer else default_fiscal_position
|
||||
|
||||
def create_order_line(product, quantity):
|
||||
price_unit = self.pricelist.get_product_price(product, quantity, False)
|
||||
tax_ids = fiscal_position.map_tax(product.taxes_id) if fiscal_position else product.taxes_id
|
||||
tax_values = (
|
||||
tax_ids.compute_all(price_unit, self.currency, quantity)
|
||||
if tax_ids
|
||||
else {
|
||||
'total_excluded': price_unit * quantity,
|
||||
'total_included': price_unit * quantity,
|
||||
}
|
||||
)
|
||||
return (0, 0, {
|
||||
'discount': 0,
|
||||
'id': randint(1, 1000000),
|
||||
'pack_lot_ids': [],
|
||||
'price_unit': price_unit,
|
||||
'product_id': product.id,
|
||||
'price_subtotal': tax_values['total_excluded'],
|
||||
'price_subtotal_incl': tax_values['total_included'],
|
||||
'qty': quantity,
|
||||
'tax_ids': [(6, 0, tax_ids.ids)]
|
||||
})
|
||||
|
||||
def create_payment(payment_method, amount):
|
||||
return (0, 0, {
|
||||
'amount': amount,
|
||||
'name': fields.Datetime.now(),
|
||||
'payment_method_id': payment_method.id,
|
||||
})
|
||||
|
||||
uid = uid or self.create_random_uid()
|
||||
|
||||
# 1. generate the order lines
|
||||
order_lines = [create_order_line(product, quantity) for product, quantity in product_quantity_pairs]
|
||||
|
||||
# 2. generate the payments
|
||||
total_amount_incl = sum(line[2]['price_subtotal_incl'] for line in order_lines)
|
||||
if payments is None:
|
||||
payments = [create_payment(self.cash_pm, total_amount_incl)]
|
||||
else:
|
||||
payments = [
|
||||
create_payment(pm, amount)
|
||||
for pm, amount in payments
|
||||
]
|
||||
|
||||
# 3. complete the fields of the order_data
|
||||
total_amount_base = sum(line[2]['price_subtotal'] for line in order_lines)
|
||||
return {
|
||||
'data': {
|
||||
'amount_paid': sum(payment[2]['amount'] for payment in payments),
|
||||
'amount_return': 0,
|
||||
'amount_tax': total_amount_incl - total_amount_base,
|
||||
'amount_total': total_amount_incl,
|
||||
'creation_date': fields.Datetime.to_string(fields.Datetime.now()),
|
||||
'fiscal_position_id': fiscal_position.id,
|
||||
'pricelist_id': self.config.pricelist_id.id,
|
||||
'lines': order_lines,
|
||||
'name': 'Order %s' % uid,
|
||||
'partner_id': customer and customer.id,
|
||||
'pos_session_id': self.pos_session.id,
|
||||
'sequence_number': 2,
|
||||
'statement_ids': payments,
|
||||
'uid': uid,
|
||||
'user_id': self.pos_manager.id,
|
||||
},
|
||||
'id': uid,
|
||||
'to_invoice': is_invoiced,
|
||||
}
|
||||
|
||||
def create_product(self, name, category, lst_price, standard_price=None, tax_ids=None, sale_account=None):
|
||||
product = self.env['product.product'].create({
|
||||
'type': 'product',
|
||||
'available_in_pos': True,
|
||||
'taxes_id': [(5, 0, 0)] if not tax_ids else [(6, 0, tax_ids)],
|
||||
'name': name,
|
||||
'categ_id': category.id,
|
||||
'lst_price': lst_price,
|
||||
'standard_price': standard_price if standard_price else 0.0,
|
||||
})
|
||||
product.invoice_policy = 'delivery'
|
||||
if sale_account:
|
||||
product.property_account_income_id = sale_account
|
||||
return product
|
||||
|
||||
def adjust_inventory(self, products, quantities):
|
||||
""" Adjust inventory of the given products
|
||||
"""
|
||||
inventory = self.env['stock.inventory'].create({
|
||||
'name': 'Inventory adjustment'
|
||||
})
|
||||
for product, qty in zip(products, quantities):
|
||||
self.env['stock.inventory.line'].create({
|
||||
'product_id': product.id,
|
||||
'product_uom_id': self.env.ref('uom.product_uom_unit').id,
|
||||
'inventory_id': inventory.id,
|
||||
'product_qty': qty,
|
||||
'location_id': self.env.ref('stock.stock_location_components').id,
|
||||
})
|
||||
inventory._action_start()
|
||||
inventory.action_validate()
|
||||
|
||||
def open_new_session(self):
|
||||
""" Used to open new pos session in each configuration.
|
||||
|
||||
- The idea is to properly set values that are constant
|
||||
and commonly used in an open pos session.
|
||||
- Calling this method is also a prerequisite for using
|
||||
`self.create_ui_order_data` function.
|
||||
|
||||
Fields:
|
||||
* config : the pos.config currently being used.
|
||||
Its value is set at `self.setUp` of the inheriting
|
||||
test class.
|
||||
* session : the current_session_id of config
|
||||
* currency : currency of the current pos.session
|
||||
* pricelist : the default pricelist of the session
|
||||
* cash_pm : cash payment method of the session
|
||||
* bank_pm : bank payment method of the session
|
||||
* cash_split_pm : credit payment method of the session
|
||||
"""
|
||||
self.config.open_session_cb()
|
||||
self.pos_session = self.config.current_session_id
|
||||
self.currency = self.pos_session.currency_id
|
||||
self.pricelist = self.pos_session.config_id.pricelist_id
|
||||
self.cash_pm = self.pos_session.payment_method_ids.filtered(lambda pm: pm.is_cash_count and not pm.split_transactions)[:1]
|
||||
self.bank_pm = self.pos_session.payment_method_ids.filtered(lambda pm: not pm.is_cash_count and not pm.split_transactions)[:1]
|
||||
self.cash_split_pm = self.pos_session.payment_method_ids.filtered(lambda pm: pm.is_cash_count and pm.split_transactions)[:1]
|
||||
|
||||
@@ -48,6 +48,13 @@ class TestAngloSaxonCommon(common.TransactionCase):
|
||||
self.sale_journal = self.env['account.journal'].create({'name': 'SALE journal', 'type': 'sale', 'code': 'INV00'})
|
||||
self.pos_config.invoice_journal_id = self.sale_journal
|
||||
self.pos_config.journal_ids = [self.cash_journal.id]
|
||||
self.cash_payment_method = self.env['pos.payment.method'].create({
|
||||
'name': 'Cash Test',
|
||||
'is_cash_count': True,
|
||||
'cash_journal_id': self.cash_journal.id,
|
||||
'receivable_account_id': self.account.id,
|
||||
})
|
||||
self.pos_config.write({'payment_method_ids': [(6, 0, self.cash_payment_method.ids)]})
|
||||
|
||||
|
||||
class TestAngloSaxonFlow(TestAngloSaxonCommon):
|
||||
@@ -56,17 +63,8 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
|
||||
# This test will check that the correct journal entries are created when a product in real time valuation
|
||||
# is sold in a company using anglo-saxon
|
||||
self.pos_config.open_session_cb()
|
||||
self.pos_config.current_session_id.write({'journal_ids': [(6, 0, [self.cash_journal.id])]})
|
||||
current_session = self.pos_config.current_session_id
|
||||
self.cash_journal.loss_account_id = self.account
|
||||
self.pos_statement = self.Statement.create({
|
||||
'balance_start': 0.0,
|
||||
'balance_end_real': 0.0,
|
||||
'date': time.strftime('%Y-%m-%d'),
|
||||
'journal_id': self.cash_journal.id,
|
||||
'company_id': self.company.id,
|
||||
'name': 'pos session test',
|
||||
})
|
||||
self.pos_config.current_session_id.write({'statement_ids': [(6, 0, [self.pos_statement.id])]})
|
||||
|
||||
# I create a PoS order with 1 unit of New product at 450 EUR
|
||||
self.pos_order_pos0 = self.PosOrder.create({
|
||||
@@ -93,7 +91,7 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
|
||||
context_make_payment = {"active_ids": [self.pos_order_pos0.id], "active_id": self.pos_order_pos0.id}
|
||||
self.pos_make_payment_0 = self.PosMakePayment.with_context(context_make_payment).create({
|
||||
'amount': 450.0,
|
||||
'journal_id': self.cash_journal.id,
|
||||
'payment_method_id': self.cash_payment_method.id,
|
||||
})
|
||||
|
||||
# I click on the validate button to register the payment.
|
||||
@@ -110,10 +108,14 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
|
||||
current_session_id.action_pos_session_close()
|
||||
self.assertEqual(current_session_id.state, 'closed', 'Check that session is closed')
|
||||
|
||||
# Check if there is account_move in the order.
|
||||
# There shouldn't be because the order is not invoiced.
|
||||
self.assertFalse(self.pos_order_pos0.account_move, 'There should be no invoice in the order.')
|
||||
|
||||
# I test that the generated journal entries are correct.
|
||||
account_output = self.category.property_stock_account_output_categ_id
|
||||
expense_account = self.category.property_account_expense_categ_id
|
||||
aml = self.pos_order_pos0.account_move.line_ids
|
||||
aml = current_session.move_id.line_ids
|
||||
aml_output = aml.filtered(lambda l: l.account_id.id == account_output.id)
|
||||
aml_expense = aml.filtered(lambda l: l.account_id.id == expense_account.id)
|
||||
self.assertEqual(aml_output.credit, self.product.standard_price, "Cost of Good Sold entry missing or mismatching")
|
||||
@@ -140,8 +142,8 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
|
||||
self.assertEqual(self.product.value_svl, 30, "Value should be (5*5 + 5*1) = 30")
|
||||
self.assertEqual(self.product.quantity_svl, 10)
|
||||
|
||||
self.pos_config.open_session_cb()
|
||||
self.pos_config.module_account = True
|
||||
self.pos_config.open_session_cb()
|
||||
|
||||
pos_order_values = {
|
||||
'company_id': self.company.id,
|
||||
@@ -172,6 +174,7 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
|
||||
context_make_payment = {"active_ids": [pos_order_pos0.id], "active_id": pos_order_pos0.id}
|
||||
self.pos_make_payment_0 = self.PosMakePayment.with_context(context_make_payment).create({
|
||||
'amount': 7 * 450.0,
|
||||
'payment_method_id': self.cash_payment_method.id,
|
||||
})
|
||||
|
||||
# register the payment
|
||||
@@ -183,8 +186,11 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
|
||||
current_session_id.action_pos_session_validate()
|
||||
|
||||
# check the anglo saxon move lines
|
||||
line = pos_order_pos0.account_move.line_ids.filtered(lambda l: l.debit and l.account_id == self.category.property_account_expense_categ_id)
|
||||
self.assertEqual(pos_order_pos0.account_move.journal_id, self.pos_config.journal_id)
|
||||
# with uninvoiced orders, the account_move field of pos.order is empty.
|
||||
# the accounting lines are in move_id of pos.session.
|
||||
session_move = pos_order_pos0.session_id.move_id
|
||||
line = session_move.line_ids.filtered(lambda l: l.debit and l.account_id == self.category.property_account_expense_categ_id)
|
||||
self.assertEqual(session_move.journal_id, self.pos_config.journal_id)
|
||||
self.assertEqual(line.debit, 27, 'As it is a fifo product, the move\'s value should be 5*5 + 2*1')
|
||||
|
||||
def test_fifo_valuation_with_invoice(self):
|
||||
@@ -194,7 +200,7 @@ class TestAngloSaxonFlow(TestAngloSaxonCommon):
|
||||
context_make_payment = {"active_ids": [pos_order_pos0.id], "active_id": pos_order_pos0.id}
|
||||
self.pos_make_payment_0 = self.PosMakePayment.with_context(context_make_payment).create({
|
||||
'amount': 7 * 450.0,
|
||||
'journal_id': self.cash_journal.id,
|
||||
'payment_method_id': self.cash_payment_method.id,
|
||||
})
|
||||
|
||||
# register the payment
|
||||
|
||||
@@ -27,6 +27,14 @@ class TestUi(odoo.tests.HttpCase):
|
||||
'fields_id': field.id,
|
||||
'value': 'account.account,' + str(account_receivable.id)})
|
||||
|
||||
cash_journal = journal_obj.create({
|
||||
'name': 'Cash Test',
|
||||
'type': 'cash',
|
||||
'company_id': main_company.id,
|
||||
'code': 'CSH',
|
||||
'sequence': 10,
|
||||
})
|
||||
|
||||
# test an extra price on an attribute
|
||||
pear = env.ref('point_of_sale.whiteboard')
|
||||
attribute_value = env['product.attribute.value'].create({
|
||||
@@ -287,11 +295,11 @@ class TestUi(odoo.tests.HttpCase):
|
||||
})],
|
||||
'journal_id': test_sale_journal.id,
|
||||
'invoice_journal_id': test_sale_journal.id,
|
||||
'journal_ids': [(0, 0, {'name': 'Cash Journal - Test',
|
||||
'code': 'TSC',
|
||||
'type': 'cash',
|
||||
'company_id': main_company.id,
|
||||
'journal_user': True})],
|
||||
'payment_method_ids': [(0, 0, { 'name': 'Cash',
|
||||
'is_cash_count': True,
|
||||
'cash_journal_id': cash_journal.id,
|
||||
'receivable_account_id': account_receivable.id,
|
||||
})],
|
||||
'use_pricelist': True,
|
||||
'pricelist_id': public_pricelist.id,
|
||||
'available_pricelist_ids': [(4, pricelist.id) for pricelist in all_pricelists],
|
||||
|
||||
@@ -4,18 +4,13 @@ import time
|
||||
import odoo
|
||||
from odoo import fields
|
||||
from odoo.tools import float_compare, mute_logger, test_reports
|
||||
from odoo.tests.common import Form
|
||||
from odoo.addons.point_of_sale.tests.common import TestPointOfSaleCommon
|
||||
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
|
||||
def test_register_open(self):
|
||||
"""
|
||||
In order to test the Point of Sale module, I will open all cash registers through the wizard
|
||||
"""
|
||||
# open all statements/cash registers
|
||||
self.env['pos.open.statement'].create({}).open_statement()
|
||||
|
||||
def test_order_refund(self):
|
||||
self.pos_config.open_session_cb()
|
||||
@@ -47,10 +42,18 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
})],
|
||||
'amount_total': 1710.0,
|
||||
'amount_tax': 0.0,
|
||||
'amount_paid': 1710.0,
|
||||
'amount_paid': 0.0,
|
||||
'amount_return': 0.0,
|
||||
})
|
||||
|
||||
payment_context = {"active_ids": order.ids, "active_id": order.id}
|
||||
order_payment = self.PosMakePayment.with_context(**payment_context).create({
|
||||
'amount': order.amount_total,
|
||||
'payment_method_id': self.cash_payment_method.id
|
||||
})
|
||||
order_payment.with_context(**payment_context).check()
|
||||
self.assertAlmostEqual(order.amount_total, order.amount_paid, msg='Order should be fully paid.')
|
||||
|
||||
# I create a refund
|
||||
refund_action = order.refund()
|
||||
refund = self.PosOrder.browse(refund_action['res_id'])
|
||||
@@ -60,13 +63,18 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
|
||||
payment_context = {"active_ids": refund.ids, "active_id": refund.id}
|
||||
refund_payment = self.PosMakePayment.with_context(**payment_context).create({
|
||||
'amount': refund.amount_total
|
||||
'amount': refund.amount_total,
|
||||
'payment_method_id': self.cash_payment_method.id,
|
||||
})
|
||||
|
||||
# I click on the validate button to register the payment.
|
||||
refund_payment.with_context(**payment_context).check()
|
||||
|
||||
self.assertEqual(refund.state, 'paid', "The refund is not marked as paid")
|
||||
self.assertTrue(refund.payment_ids.payment_method_id.is_cash_count, msg='There should only be one payment and paid in cash.')
|
||||
|
||||
current_session.action_pos_session_closing_control()
|
||||
self.assertEqual(current_session.state, 'closed', msg='State of current session should be closed.')
|
||||
|
||||
def test_order_to_picking(self):
|
||||
"""
|
||||
@@ -287,7 +295,6 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
# I close the session to generate the journal entries
|
||||
self.pos_config.current_session_id.action_pos_session_closing_control()
|
||||
|
||||
|
||||
def test_order_to_invoice(self):
|
||||
|
||||
def compute_tax(product, price, qty=1, taxes=None):
|
||||
@@ -350,13 +357,16 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
|
||||
# I generate an invoice from the order
|
||||
res = self.pos_order_pos1.action_pos_order_invoice()
|
||||
self.assertIn('res_id', res, "No invoice created")
|
||||
self.assertIn('res_id', res, "Invoice should be created")
|
||||
|
||||
# I test that the total of the attached invoice is correct
|
||||
invoice = self.env['account.move'].browse(res['res_id'])
|
||||
self.assertAlmostEqual(
|
||||
invoice.amount_total, self.pos_order_pos1.amount_total, places=2, msg="Invoice not correct")
|
||||
|
||||
# I close the session to generate the journal entries
|
||||
current_session.action_pos_session_closing_control()
|
||||
|
||||
"""In order to test the reports on Bank Statement defined in point_of_sale module, I create a bank statement line, confirm it and print the reports"""
|
||||
|
||||
# I select the period and journal for the bank statement
|
||||
@@ -450,11 +460,9 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
'sequence_number': 2,
|
||||
'statement_ids': [[0,
|
||||
0,
|
||||
{'account_id': self.env.user.partner_id.property_account_receivable_id.id,
|
||||
'amount': untax + atax,
|
||||
'journal_id': self.pos_config.journal_ids[0].id,
|
||||
{'amount': untax + atax,
|
||||
'name': fields.Datetime.now(),
|
||||
'statement_id': current_session.statement_ids[0].id}]],
|
||||
'payment_method_id': self.cash_payment_method.id}]],
|
||||
'uid': '00042-003-0014',
|
||||
'user_id': self.env.uid},
|
||||
'id': '00042-003-0014',
|
||||
@@ -486,11 +494,9 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
'sequence_number': self.pos_config.journal_id.id,
|
||||
'statement_ids': [[0,
|
||||
0,
|
||||
{'account_id': self.env.user.partner_id.property_account_receivable_id.id,
|
||||
'amount': untax + atax,
|
||||
'journal_id': self.pos_config.journal_ids[0].id,
|
||||
{'amount': untax + atax,
|
||||
'name': fields.Datetime.now(),
|
||||
'statement_id': current_session.statement_ids[0].id}]],
|
||||
'payment_method_id': self.credit_payment_method.id}]],
|
||||
'uid': '00043-003-0014',
|
||||
'user_id': self.env.uid},
|
||||
'id': '00043-003-0014',
|
||||
@@ -522,11 +528,9 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
'sequence_number': self.pos_config.journal_id.id,
|
||||
'statement_ids': [[0,
|
||||
0,
|
||||
{'account_id': self.env.user.partner_id.property_account_receivable_id.id,
|
||||
'amount': untax + atax,
|
||||
'journal_id': self.pos_config.journal_ids[0].id,
|
||||
{'amount': untax + atax,
|
||||
'name': fields.Datetime.now(),
|
||||
'statement_id': current_session.statement_ids[0].id}]],
|
||||
'payment_method_id': self.bank_payment_method.id}]],
|
||||
'uid': '00044-003-0014',
|
||||
'user_id': self.env.uid},
|
||||
'id': '00044-003-0014',
|
||||
@@ -588,19 +592,39 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
untax = res['total_excluded']
|
||||
return untax, sum(tax.get('amount', 0.0) for tax in res['taxes'])
|
||||
|
||||
# make a config that has currency different from the company
|
||||
eur_pricelist = self.partner1.property_product_pricelist.copy(default={'currency_id': self.env.ref('base.EUR').id})
|
||||
sale_journal = self.env['account.journal'].create({
|
||||
'name': 'PoS Sale EUR',
|
||||
'type': 'sale',
|
||||
'code': 'POSE',
|
||||
'company_id': self.company.id,
|
||||
'sequence': 12,
|
||||
'currency_id': self.env.ref('base.EUR').id
|
||||
})
|
||||
eur_config = self.pos_config.create({
|
||||
'name': 'Shop EUR Test',
|
||||
'module_account': False,
|
||||
'journal_id': sale_journal.id,
|
||||
'use_pricelist': True,
|
||||
'available_pricelist_ids': [(6, 0, eur_pricelist.ids)],
|
||||
'pricelist_id': eur_pricelist.id,
|
||||
'payment_method_ids': [(6, 0, self.bank_payment_method.ids)]
|
||||
})
|
||||
|
||||
# I click on create a new session button
|
||||
self.pos_config.open_session_cb()
|
||||
current_session = self.pos_config.current_session_id
|
||||
eur_config.open_session_cb()
|
||||
current_session = eur_config.current_session_id
|
||||
|
||||
# I create a PoS order with 2 units of PCSC234 at 450 EUR (Tax Incl)
|
||||
# and 3 units of PCSC349 at 300 EUR. (Tax Excl)
|
||||
|
||||
untax1, atax1 = compute_tax(self.product3, 450*0.95, 2)
|
||||
untax2, atax2 = compute_tax(self.product4, 300*0.95, 3)
|
||||
untax1, atax1 = compute_tax(self.product3, 450, 2)
|
||||
untax2, atax2 = compute_tax(self.product4, 300, 3)
|
||||
self.pos_order_pos0 = self.PosOrder.create({
|
||||
'company_id': self.company_id,
|
||||
'session_id': current_session.id,
|
||||
'pricelist_id': self.partner1.property_product_pricelist.copy(default={'currency_id': self.env.ref('base.EUR').id}).id,
|
||||
'pricelist_id': eur_pricelist.id,
|
||||
'partner_id': self.partner1.id,
|
||||
'lines': [(0, 0, {
|
||||
'name': "OL/0001",
|
||||
@@ -630,14 +654,15 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
# I check that the total of the order is now equal to (450*2 +
|
||||
# 300*3*1.05)*0.95
|
||||
self.assertLess(
|
||||
abs(self.pos_order_pos0.amount_total - (450 * 2 + 300 * 3 * 1.05) * 0.95),
|
||||
abs(self.pos_order_pos0.amount_total - (450 * 2 + 300 * 3 * 1.05)),
|
||||
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
|
||||
context_make_payment = {"active_ids": [self.pos_order_pos0.id], "active_id": self.pos_order_pos0.id}
|
||||
self.pos_make_payment_0 = self.PosMakePayment.with_context(context_make_payment).create({
|
||||
'amount': 100.0
|
||||
'amount': 100.0,
|
||||
'payment_method_id': self.bank_payment_method.id,
|
||||
})
|
||||
|
||||
# I click on the validate button to register the payment.
|
||||
@@ -652,14 +677,15 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
defs = self.pos_make_payment_0.with_context({'active_id': self.pos_order_pos0.id}).default_get(['amount'])
|
||||
|
||||
self.assertLess(
|
||||
abs(defs['amount'] - ((450 * 2 + 300 * 3 * 1.05) * 0.95 - 100.0)), 0.01, "The remaining balance is incorrect.")
|
||||
abs(defs['amount'] - ((450 * 2 + 300 * 3 * 1.05) - 100.0)), 0.01, "The remaining balance is incorrect.")
|
||||
|
||||
#'I pay the remaining balance.
|
||||
context_make_payment = {
|
||||
"active_ids": [self.pos_order_pos0.id], "active_id": self.pos_order_pos0.id}
|
||||
|
||||
self.pos_make_payment_1 = self.PosMakePayment.with_context(context_make_payment).create({
|
||||
'amount': (450 * 2 + 300 * 3 * 1.05) * 0.95 - 100.0
|
||||
'amount': (450 * 2 + 300 * 3 * 1.05) - 100.0,
|
||||
'payment_method_id': self.bank_payment_method.id,
|
||||
})
|
||||
|
||||
# I click on the validate button to register the payment.
|
||||
@@ -669,20 +695,20 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
self.assertEqual(self.pos_order_pos0.state, 'paid', 'Order should be in paid state.')
|
||||
|
||||
# I generate the journal entries
|
||||
self.pos_order_pos0._create_account_move_line()
|
||||
current_session.action_pos_session_validate()
|
||||
|
||||
# I test that the generated journal entry is attached to the PoS order
|
||||
self.assertTrue(self.pos_order_pos0.account_move, "Journal entry has not been attached to Pos order.")
|
||||
self.assertTrue(current_session.move_id, "Journal entry should have been attached to the session.")
|
||||
|
||||
# Check the amounts
|
||||
debit_lines = self.pos_order_pos0.account_move.mapped('line_ids.debit')
|
||||
credit_lines = self.pos_order_pos0.account_move.mapped('line_ids.credit')
|
||||
amount_currency_lines = self.pos_order_pos0.account_move.mapped('line_ids.amount_currency')
|
||||
for a, b in zip(sorted(debit_lines), [0.0, 0.0, 0.0, 0.0, 879.55]):
|
||||
debit_lines = current_session.move_id.mapped('line_ids.debit')
|
||||
credit_lines = current_session.move_id.mapped('line_ids.credit')
|
||||
amount_currency_lines = current_session.move_id.mapped('line_ids.amount_currency')
|
||||
for a, b in zip(sorted(debit_lines), [0.0, 0.0, 0.0, 0.0, 922.5]):
|
||||
self.assertAlmostEqual(a, b)
|
||||
for a, b in zip(sorted(credit_lines), [0.0, 22.5, 40.91, 388.64, 427.5]):
|
||||
for a, b in zip(sorted(credit_lines), [0.0, 22.5, 40.91, 409.09, 450]):
|
||||
self.assertAlmostEqual(a, b)
|
||||
for a, b in zip(sorted(amount_currency_lines), [-855.0, -777.27, -81.82, -45.0, 1752.75]):
|
||||
for a, b in zip(sorted(amount_currency_lines), [-900, -818.18, -81.82, -45, 1845]):
|
||||
self.assertAlmostEqual(a, b)
|
||||
|
||||
def test_order_to_invoice_no_tax(self):
|
||||
@@ -731,7 +757,7 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
# I check that the order is marked as paid and there is no invoice
|
||||
# attached to it
|
||||
self.assertEqual(self.pos_order_pos1.state, 'paid', "Order should be in paid state.")
|
||||
self.assertFalse(self.pos_order_pos1.account_move, 'Invoice should not be attached to order.')
|
||||
self.assertFalse(self.pos_order_pos1.account_move, 'Invoice should not be attached to order yet.')
|
||||
|
||||
# I generate an invoice from the order
|
||||
res = self.pos_order_pos1.action_pos_order_invoice()
|
||||
@@ -744,3 +770,5 @@ class TestPointOfSaleFlow(TestPointOfSaleCommon):
|
||||
|
||||
for iline in invoice.invoice_line_ids:
|
||||
self.assertFalse(iline.tax_ids)
|
||||
|
||||
self.pos_config.current_session_id.action_pos_session_closing_control()
|
||||
|
||||
@@ -0,0 +1,423 @@
|
||||
import odoo
|
||||
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestPoSBasicConfig(TestPoSCommon):
|
||||
""" Test PoS with basic configuration
|
||||
|
||||
The tests contain base scenarios in using pos.
|
||||
More specialized cases are tested in other tests.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestPoSBasicConfig, self).setUp()
|
||||
self.config = self.basic_config
|
||||
self.product1 = self.create_product('Product 1', self.categ_basic, 10.0, 5)
|
||||
self.product2 = self.create_product('Product 2', self.categ_basic, 20.0, 10)
|
||||
self.product3 = self.create_product('Product 3', self.categ_basic, 30.0, 15)
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [100, 50, 50])
|
||||
|
||||
def test_orders_no_invoiced(self):
|
||||
""" Test for orders without invoice
|
||||
|
||||
3 orders
|
||||
- first 2 orders with cash payment
|
||||
- last order with bank payment
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
| order | payments | invoiced? | product | qty | total |
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
| order 1 | cash | no | product1 | 10 | 100 |
|
||||
| | | | product2 | 5 | 100 |
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
| order 2 | cash | no | product2 | 7 | 140 |
|
||||
| | | | product3 | 1 | 30 |
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
| order 3 | bank | no | product1 | 1 | 10 |
|
||||
| | | | product2 | 3 | 60 |
|
||||
| | | | product3 | 5 | 150 |
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale | -590 |
|
||||
| pos receivable cash | 370 |
|
||||
| pos receivable bank | 220 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.0 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
start_qty_available = {
|
||||
self.product1: self.product1.qty_available,
|
||||
self.product2: self.product2.qty_available,
|
||||
self.product3: self.product3.qty_available,
|
||||
}
|
||||
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 5)]))
|
||||
orders.append(self.create_ui_order_data([(self.product2, 7), (self.product3, 1)]))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 1), (self.product3, 5), (self.product2, 3)],
|
||||
payments=[(self.bank_pm, 220)]
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# check product qty_available after syncing the order
|
||||
self.assertEqual(
|
||||
self.product1.qty_available + 11,
|
||||
start_qty_available[self.product1],
|
||||
)
|
||||
self.assertEqual(
|
||||
self.product2.qty_available + 15,
|
||||
start_qty_available[self.product2],
|
||||
)
|
||||
self.assertEqual(
|
||||
self.product3.qty_available + 6,
|
||||
start_qty_available[self.product3],
|
||||
)
|
||||
|
||||
# picking and stock moves should be in done state
|
||||
for order in self.pos_session.order_ids:
|
||||
self.assertEqual(
|
||||
order.picking_id.state,
|
||||
'done',
|
||||
'Picking should be in done state.'
|
||||
)
|
||||
move_lines = order.picking_id.move_lines
|
||||
self.assertEqual(
|
||||
move_lines.mapped('state'),
|
||||
['done'] * len(move_lines),
|
||||
'Move Lines should be in done state.'
|
||||
)
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check accounting values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sales_line = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(sales_line.balance, -590.0, msg='Sales line balance should be equal to total orders amount.')
|
||||
|
||||
receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_bank.balance, 220.0, msg='Bank receivable should be equal to the total bank payments.')
|
||||
|
||||
receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_cash.balance, 370.0, msg='Cash receivable should be equal to the total cash payments.')
|
||||
|
||||
self.assertTrue(receivable_line_cash.full_reconcile_id, msg='Cash receivable line should be fully-reconciled.')
|
||||
|
||||
def test_orders_with_invoiced(self):
|
||||
""" Test for orders: one with invoice
|
||||
|
||||
3 orders
|
||||
- order 1, paid by cash
|
||||
- order 2, paid by bank
|
||||
- order 3, paid by bank, invoiced
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order | payments | invoiced? | product | qty | total |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order 1 | cash | no | product1 | 6 | 60 |
|
||||
| | | | product2 | 3 | 60 |
|
||||
| | | | product3 | 1 | 30 |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order 2 | bank | no | product1 | 1 | 10 |
|
||||
| | | | product2 | 20 | 400 |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order 3 | bank | yes, customer | product1 | 10 | 100 |
|
||||
| | | | product3 | 1 | 30 |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale | -560 |
|
||||
| pos receivable cash | 150 |
|
||||
| pos receivable bank | 540 |
|
||||
| receivable | -130 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.0 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
start_qty_available = {
|
||||
self.product1: self.product1.qty_available,
|
||||
self.product2: self.product2.qty_available,
|
||||
self.product3: self.product3.qty_available,
|
||||
}
|
||||
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product3, 1), (self.product1, 6), (self.product2, 3)],
|
||||
payments=[(self.cash_pm, 150)],
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 20), (self.product1, 1)],
|
||||
payments=[(self.bank_pm, 410)],
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 10), (self.product3, 1)],
|
||||
payments=[(self.bank_pm, 130)],
|
||||
customer=self.customer,
|
||||
is_invoiced=True,
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# check product qty_available after syncing the order
|
||||
self.assertEqual(
|
||||
self.product1.qty_available + 17,
|
||||
start_qty_available[self.product1],
|
||||
)
|
||||
self.assertEqual(
|
||||
self.product2.qty_available + 23,
|
||||
start_qty_available[self.product2],
|
||||
)
|
||||
self.assertEqual(
|
||||
self.product3.qty_available + 2,
|
||||
start_qty_available[self.product3],
|
||||
)
|
||||
|
||||
# picking and stock moves should be in done state
|
||||
# no exception for invoiced orders
|
||||
for order in self.pos_session.order_ids:
|
||||
self.assertEqual(
|
||||
order.picking_id.state,
|
||||
'done',
|
||||
'Picking should be in done state.'
|
||||
)
|
||||
move_lines = order.picking_id.move_lines
|
||||
self.assertEqual(
|
||||
move_lines.mapped('state'),
|
||||
['done'] * len(move_lines),
|
||||
'Move Lines should be in done state.'
|
||||
)
|
||||
|
||||
# check account move in the invoiced order
|
||||
invoiced_order = self.pos_session.order_ids.filtered(lambda order: order.account_move)
|
||||
self.assertEqual(1, len(invoiced_order), 'Only one order is invoiced in this test.')
|
||||
invoice = invoiced_order.account_move
|
||||
self.assertAlmostEqual(invoice.amount_total, 130, msg='Amount total should be 130. Product is untaxed.')
|
||||
invoice_receivable_line = invoice.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sales_line = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(sales_line.balance, -(orders_total - invoice.amount_total), msg='Sales line should be total order minus invoiced order.')
|
||||
|
||||
pos_receivable_line_bank = session_move.line_ids.filtered(
|
||||
lambda line: self.bank_pm.name in line.name and line.account_id == self.bank_pm.receivable_account_id
|
||||
)
|
||||
self.assertAlmostEqual(pos_receivable_line_bank.balance, 540.0, msg='Bank receivable should be equal to the total bank payments.')
|
||||
|
||||
pos_receivable_line_cash = session_move.line_ids.filtered(
|
||||
lambda line: self.cash_pm.name in line.name and line.account_id == self.bank_pm.receivable_account_id
|
||||
)
|
||||
self.assertAlmostEqual(pos_receivable_line_cash.balance, 150.0, msg='Cash receivable should be equal to the total cash payments.')
|
||||
|
||||
receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
self.assertAlmostEqual(receivable_line.balance, -invoice.amount_total)
|
||||
|
||||
# cash receivable and invoice receivable lines should be fully reconciled
|
||||
self.assertTrue(pos_receivable_line_cash.full_reconcile_id)
|
||||
self.assertTrue(receivable_line.full_reconcile_id)
|
||||
|
||||
# matching number of the receivable lines should be the same
|
||||
self.assertEqual(receivable_line.full_reconcile_id, invoice_receivable_line.full_reconcile_id)
|
||||
|
||||
def test_return_order(self):
|
||||
""" Test return order
|
||||
|
||||
2 orders
|
||||
- 2nd order is returned
|
||||
|
||||
Orders
|
||||
======
|
||||
+------------------+----------+-----------+----------+-----+-------+
|
||||
| order | payments | invoiced? | product | qty | total |
|
||||
+------------------+----------+-----------+----------+-----+-------+
|
||||
| order 1 | bank | no | product1 | 1 | 10 |
|
||||
| | | | product2 | 5 | 100 |
|
||||
+------------------+----------+-----------+----------+-----+-------+
|
||||
| order 2 | cash | no | product1 | 3 | 30 |
|
||||
| | | | product2 | 2 | 40 |
|
||||
| | | | product3 | 1 | 30 |
|
||||
+------------------+----------+-----------+----------+-----+-------+
|
||||
| order 3 (return) | cash | no | product1 | -3 | -30 |
|
||||
| | | | product2 | -2 | -40 |
|
||||
| | | | product3 | -1 | -30 |
|
||||
+------------------+----------+-----------+----------+-----+-------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale (sales) | -210 |
|
||||
| sale (refund) | 100 |
|
||||
| pos receivable bank | 110 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.0 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
start_qty_available = {
|
||||
self.product1: self.product1.qty_available,
|
||||
self.product2: self.product2.qty_available,
|
||||
self.product3: self.product3.qty_available,
|
||||
}
|
||||
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 1), (self.product2, 5)],
|
||||
payments=[(self.bank_pm, 110)]
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 3), (self.product2, 2), (self.product3, 1)],
|
||||
payments=[(self.cash_pm, 100)],
|
||||
uid='12345-123-1234'
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(2, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# return order
|
||||
order_to_return = self.pos_session.order_ids.filtered(lambda order: '12345-123-1234' in order.pos_reference)
|
||||
order_to_return.refund()
|
||||
refund_order = self.pos_session.order_ids.filtered(lambda order: order.state == 'draft')
|
||||
|
||||
# check if amount to pay
|
||||
self.assertAlmostEqual(refund_order.amount_total - refund_order.amount_paid, -100)
|
||||
|
||||
# pay the refund
|
||||
context_make_payment = {"active_ids": [refund_order.id], "active_id": refund_order.id}
|
||||
make_payment = self.env['pos.make.payment'].with_context(context_make_payment).create({
|
||||
'payment_method_id': self.cash_pm.id,
|
||||
'amount': -100,
|
||||
})
|
||||
make_payment.check()
|
||||
self.assertEqual(refund_order.state, 'paid', 'Payment is registered, order should be paid.')
|
||||
self.assertAlmostEqual(refund_order.amount_paid, -100.0, msg='Amount paid for return order should be negative.')
|
||||
|
||||
# check product qty_available after syncing the order
|
||||
self.assertEqual(
|
||||
self.product1.qty_available + 1,
|
||||
start_qty_available[self.product1],
|
||||
)
|
||||
self.assertEqual(
|
||||
self.product2.qty_available + 5,
|
||||
start_qty_available[self.product2],
|
||||
)
|
||||
self.assertEqual(
|
||||
self.product3.qty_available,
|
||||
start_qty_available[self.product3],
|
||||
)
|
||||
|
||||
# picking and stock moves should be in done state
|
||||
# no exception of return orders
|
||||
for order in self.pos_session.order_ids:
|
||||
self.assertEqual(
|
||||
order.picking_id.state,
|
||||
'done',
|
||||
'Picking should be in done state.'
|
||||
)
|
||||
move_lines = order.picking_id.move_lines
|
||||
self.assertEqual(
|
||||
move_lines.mapped('state'),
|
||||
['done'] * len(move_lines),
|
||||
'Move Lines should be in done state.'
|
||||
)
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sale_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(len(sale_lines), 2, 'There should be lines for both sales and refund.')
|
||||
self.assertAlmostEqual(sum(sale_lines.mapped('balance')), -110.0)
|
||||
|
||||
receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_bank.balance, 110.0)
|
||||
|
||||
# net cash in the session is zero, thus, there should be no receivable cash line.
|
||||
receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertFalse(receivable_line_cash, 'There should be no receivable cash line because both the order and return order are paid with cash - they cancelled.')
|
||||
|
||||
def test_split_cash_payments(self):
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 10), (self.product2, 5)],
|
||||
payments=[(self.cash_split_pm, 100), (self.bank_pm, 100)]
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 7), (self.product3, 1)],
|
||||
payments=[(self.cash_split_pm, 70), (self.bank_pm, 100)]
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 1), (self.product3, 5), (self.product2, 3)],
|
||||
payments=[(self.cash_split_pm, 120), (self.bank_pm, 100)]
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
account_move = self.pos_session.move_id
|
||||
|
||||
bank_receivable_lines = account_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertEqual(len(bank_receivable_lines), 1, msg='Bank receivable lines should only have one line because it\'s supposed to be combined.')
|
||||
self.assertAlmostEqual(bank_receivable_lines.balance, 300.0, msg='Bank receivable should be equal to the total bank payments.')
|
||||
|
||||
cash_receivable_lines = account_move.line_ids.filtered(lambda line: self.cash_split_pm.name in line.name)
|
||||
self.assertEqual(len(cash_receivable_lines), 3, msg='There should be a number of cash receivable lines because the cash_pm is `split_transactions`.')
|
||||
self.assertAlmostEqual(sum(cash_receivable_lines.mapped('balance')), 290, msg='Total cash receivable balance should be equal to the total cash payments.')
|
||||
|
||||
for line in cash_receivable_lines:
|
||||
self.assertTrue(line.full_reconcile_id, msg='Each cash receivable line should be fully-reconciled.')
|
||||
@@ -0,0 +1,199 @@
|
||||
import odoo
|
||||
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestPoSMultipleReceivableAccounts(TestPoSCommon):
|
||||
""" Test for invoiced orders with customers having receivable account different from default
|
||||
|
||||
Thus, for this test, there are two receivable accounts involved and are set in the
|
||||
customers.
|
||||
self.customer -> self.receivable_account
|
||||
self.other_customer -> self.other_receivable_account
|
||||
|
||||
NOTE That both receivable accounts above are different from the pos receivable account.
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestPoSMultipleReceivableAccounts, self).setUp()
|
||||
self.config = self.basic_config
|
||||
self.product1 = self.create_product(
|
||||
'Product 1',
|
||||
self.categ_basic,
|
||||
lst_price=10.99,
|
||||
standard_price=5.0,
|
||||
tax_ids=self.taxes['tax7'].ids,
|
||||
)
|
||||
self.product2 = self.create_product(
|
||||
'Product 2',
|
||||
self.categ_basic,
|
||||
lst_price=19.99,
|
||||
standard_price=10.0,
|
||||
tax_ids=self.taxes['tax10'].ids,
|
||||
sale_account=self.other_sale_account,
|
||||
)
|
||||
self.product3 = self.create_product(
|
||||
'Product 3',
|
||||
self.categ_basic,
|
||||
lst_price=30.99,
|
||||
standard_price=15.0,
|
||||
tax_ids=self.taxes['tax_group_7_10'].ids,
|
||||
)
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [100, 50, 50])
|
||||
|
||||
def test_01_invoiced_order_from_other_customer(self):
|
||||
"""
|
||||
Orders
|
||||
======
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
| order 1 | cash | no | product1 | 10 | 109.9 | 7.69 [7%] | 117.59 |
|
||||
| | | | product2 | 10 | 181.73 | 18.17 [10%] | 199.9 |
|
||||
| | | | product3 | 10 | 281.73 | 19.72 [7%] + 28.17 [10%] | 329.62 |
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
| order 2 | bank | no | product1 | 5 | 54.95 | 3.85 [7%] | 58.80 |
|
||||
| | | | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
| order 3 | bank | yes | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
| | | | product3 | 5 | 140.86 | 9.86 [7%] + 14.09 [10%] | 164.81 |
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale_account | -164.85 |
|
||||
| sale_account | -281.73 |
|
||||
| other_sale_account | -272.59 |
|
||||
| tax 7% | -31.26 |
|
||||
| tax 10% | -55.43 |
|
||||
| pos receivable cash | 647.11 |
|
||||
| pos receivable bank | 423.51 |
|
||||
| other receivable | -264.76 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.00 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 10), (self.product3, 10)]))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 5), (self.product2, 5)],
|
||||
payments=[(self.bank_pm, 158.75)],
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 5), (self.product3, 5)],
|
||||
payments=[(self.bank_pm, 264.76)],
|
||||
customer=self.other_customer,
|
||||
is_invoiced=True,
|
||||
uid='09876-098-0987',
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# check if there is one invoiced order
|
||||
self.assertEqual(len(self.pos_session.order_ids.filtered(lambda order: order.state == 'invoiced')), 1, 'There should only be one invoiced order.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
session_move = self.pos_session.move_id
|
||||
# There should be no line corresponding the original receivable account
|
||||
# But there should be a line for other_receivable_account because
|
||||
# that is the property_account_receivable_id of the customer
|
||||
# of the invoiced order.
|
||||
receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
self.assertFalse(receivable_line, msg='There should be no move line for the original receivable account.')
|
||||
other_receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.other_receivable_account)
|
||||
self.assertAlmostEqual(other_receivable_line.balance, -264.76)
|
||||
|
||||
def test_02_all_orders_invoiced_mixed_customers(self):
|
||||
"""
|
||||
Orders
|
||||
======
|
||||
+---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
|
||||
| order 1 | cash | yes, other_customer | product1 | 10 | 109.90 | 7.69 [7%] | 117.59 |
|
||||
| | | | product2 | 10 | 181.73 | 18.17 [10%] | 199.90 |
|
||||
| | | | product3 | 10 | 281.73 | 19.72 [7%] + 28.17 [10%] | 329.62 |
|
||||
+---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
|
||||
| order 2 | bank | yes, customer | product1 | 5 | 54.95 | 3.85 [7%] | 58.80 |
|
||||
| | | | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
+---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
|
||||
| order 3 | bank | yes, other customer | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
| | | | product3 | 5 | 140.86 | 9.86 [7%] + 14.09 [10%] | 164.81 |
|
||||
+---------+----------+---------------------+----------+-----+---------+--------------------------+--------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+------------------+---------+
|
||||
| account | balance |
|
||||
+------------------+---------+
|
||||
| receivable cash | 647.11 |
|
||||
| receivable bank | 423.51 |
|
||||
| other receivable | -911.87 |
|
||||
| receivable | -158.75 |
|
||||
+------------------+---------+
|
||||
| Total balance | 0.00 |
|
||||
+------------------+---------+
|
||||
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 10), (self.product2, 10), (self.product3, 10)],
|
||||
customer=self.other_customer,
|
||||
is_invoiced=True,
|
||||
uid='09876-098-0987',
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 5), (self.product2, 5)],
|
||||
payments=[(self.bank_pm, 158.75)],
|
||||
customer=self.customer,
|
||||
is_invoiced=True,
|
||||
uid='09876-098-0988',
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 5), (self.product3, 5)],
|
||||
payments=[(self.bank_pm, 264.76)],
|
||||
customer=self.other_customer,
|
||||
is_invoiced=True,
|
||||
uid='09876-098-0989',
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# check if there is one invoiced order
|
||||
self.assertEqual(len(self.pos_session.order_ids.filtered(lambda order: order.state == 'invoiced')), 3, 'All orders should be invoiced.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
self.assertAlmostEqual(receivable_line.balance, -158.75)
|
||||
other_receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.other_receivable_account)
|
||||
self.assertAlmostEqual(other_receivable_line.balance, -911.87)
|
||||
receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_bank.balance, 423.51)
|
||||
receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_cash.balance, 647.11)
|
||||
@@ -0,0 +1,220 @@
|
||||
import odoo
|
||||
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestPoSMultipleSaleAccounts(TestPoSCommon):
|
||||
""" Test to orders containing products with different sale accounts
|
||||
|
||||
keywords/phrases: Different Income Accounts
|
||||
|
||||
In this test, two sale (income) accounts are involved:
|
||||
self.sale_account -> default for products because it is in the category
|
||||
self.other_sale_account -> manually set to self.product2
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestPoSMultipleSaleAccounts, self).setUp()
|
||||
self.config = self.basic_config
|
||||
self.product1 = self.create_product(
|
||||
'Product 1',
|
||||
self.categ_basic,
|
||||
lst_price=10.99,
|
||||
standard_price=5.0,
|
||||
tax_ids=self.taxes['tax7'].ids,
|
||||
)
|
||||
self.product2 = self.create_product(
|
||||
'Product 2',
|
||||
self.categ_basic,
|
||||
lst_price=19.99,
|
||||
standard_price=10.0,
|
||||
tax_ids=self.taxes['tax10'].ids,
|
||||
sale_account=self.other_sale_account,
|
||||
)
|
||||
self.product3 = self.create_product(
|
||||
'Product 3',
|
||||
self.categ_basic,
|
||||
lst_price=30.99,
|
||||
standard_price=15.0,
|
||||
tax_ids=self.taxes['tax_group_7_10'].ids,
|
||||
)
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [100, 50, 50])
|
||||
|
||||
def test_01_check_product_properties(self):
|
||||
self.assertEqual(self.product2.property_account_income_id, self.other_sale_account, 'Income account for the product2 should be the other sale account.')
|
||||
self.assertFalse(self.product1.property_account_income_id, msg='Income account for product1 should not be set.')
|
||||
self.assertFalse(self.product3.property_account_income_id, msg='Income account for product3 should not be set.')
|
||||
self.assertEqual(self.product1.categ_id.property_account_income_categ_id, self.sale_account)
|
||||
self.assertEqual(self.product3.categ_id.property_account_income_categ_id, self.sale_account)
|
||||
|
||||
def test_02_orders_without_invoice(self):
|
||||
""" orders without invoice
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
| order 1 | cash | no | product1 | 10 | 109.9 | 7.69 [7%] | 117.59 |
|
||||
| | | | product2 | 10 | 181.73 | 18.17 [10%] | 199.9 |
|
||||
| | | | product3 | 10 | 281.73 | 19.72 [7%] + 28.17 [10%] | 329.62 |
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
| order 2 | cash | no | product1 | 5 | 54.95 | 3.85 [7%] | 58.80 |
|
||||
| | | | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
| order 3 | bank | no | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
| | | | product3 | 5 | 140.86 | 9.86 [7%] + 14.09 [10%] | 164.81 |
|
||||
+---------+----------+-----------+----------+-----+---------+--------------------------+--------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale_account | -164.85 | (for the 7% base amount)
|
||||
| sale_account | -422.59 | (for the 7+10% base amount)
|
||||
| other_sale_account | -363.45 |
|
||||
| tax 7% | -41.12 |
|
||||
| tax 10% | -78.61 |
|
||||
| pos receivable bank | 264.76 |
|
||||
| pos receivable cash | 805.86 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.00 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 10), (self.product3, 10)]))
|
||||
orders.append(self.create_ui_order_data([(self.product1, 5), (self.product2, 5)]))
|
||||
orders.append(self.create_ui_order_data([(self.product2, 5), (self.product3, 5)], payments=[(self.bank_pm, 264.76)]))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sale_account_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
for balance, amount in zip(sorted(sale_account_lines.mapped('balance')), sorted([-164.85, -422.59])):
|
||||
self.assertAlmostEqual(balance, amount)
|
||||
|
||||
other_sale_account_line = session_move.line_ids.filtered(lambda line: line.account_id == self.other_sale_account)
|
||||
self.assertAlmostEqual(other_sale_account_line.balance, -363.45)
|
||||
|
||||
receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_bank.balance, 264.76)
|
||||
|
||||
receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_cash.balance, 805.86)
|
||||
|
||||
manually_calculated_taxes = (-41.12, -78.61)
|
||||
tax_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.tax_received_account)
|
||||
self.assertAlmostEqual(sum(manually_calculated_taxes), sum(tax_lines.mapped('balance')))
|
||||
for t1, t2 in zip(sorted(manually_calculated_taxes), sorted(tax_lines.mapped('balance'))):
|
||||
self.assertAlmostEqual(t1, t2, msg='Taxes should be correctly combined.')
|
||||
|
||||
self.assertTrue(receivable_line_cash.full_reconcile_id)
|
||||
|
||||
def test_03_orders_with_invoice(self):
|
||||
""" orders with invoice
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+---------------+----------+-----+---------+--------------------------+--------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+---------+----------+---------------+----------+-----+---------+--------------------------+--------+
|
||||
| order 1 | cash | no | product1 | 10 | 109.9 | 7.69 [7%] | 117.59 |
|
||||
| | | | product2 | 10 | 181.73 | 18.17 [10%] | 199.9 |
|
||||
| | | | product3 | 10 | 281.73 | 19.72 [7%] + 28.17 [10%] | 329.62 |
|
||||
+---------+----------+---------------+----------+-----+---------+--------------------------+--------+
|
||||
| order 2 | bank | no | product1 | 5 | 54.95 | 3.85 [7%] | 58.80 |
|
||||
| | | | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
+---------+----------+---------------+----------+-----+---------+--------------------------+--------+
|
||||
| order 3 | bank | yes, customer | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
| | | | product3 | 5 | 140.86 | 9.86 [7%] + 14.09 [10%] | 164.81 |
|
||||
+---------+----------+---------------+----------+-----+---------+--------------------------+--------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale_account | -164.85 | (for the 7% base amount)
|
||||
| sale_account | -281.73 | (for the 7+10% base amount)
|
||||
| other_sale_account | -272.59 |
|
||||
| tax 7% | -31.26 |
|
||||
| tax 10% | -55.43 |
|
||||
| pos receivable cash | 647.11 |
|
||||
| pos receivable bank | 423.51 |
|
||||
| receivable | -264.76 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.00 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 10), (self.product3, 10)]))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 5), (self.product2, 5)],
|
||||
payments=[(self.bank_pm, 158.75)],
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 5), (self.product3, 5)],
|
||||
payments=[(self.bank_pm, 264.76)],
|
||||
customer=self.customer,
|
||||
is_invoiced=True,
|
||||
uid='09876-098-0987',
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# check if there is one invoiced order
|
||||
self.assertEqual(len(self.pos_session.order_ids.filtered(lambda order: order.state == 'invoiced')), 1, 'There should only be one invoiced order.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sale_account_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
for balance, amount in zip(sorted(sale_account_lines.mapped('balance')), sorted([-164.85, -281.73])):
|
||||
self.assertAlmostEqual(balance, amount)
|
||||
|
||||
other_sale_account_line = session_move.line_ids.filtered(lambda line: line.account_id == self.other_sale_account)
|
||||
self.assertAlmostEqual(other_sale_account_line.balance, -272.59)
|
||||
|
||||
pos_receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(pos_receivable_line_bank.balance, 423.51)
|
||||
|
||||
pos_receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(pos_receivable_line_cash.balance, 647.11)
|
||||
|
||||
manually_calculated_taxes = (-31.26, -55.43)
|
||||
tax_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.tax_received_account)
|
||||
self.assertAlmostEqual(sum(manually_calculated_taxes), sum(tax_lines.mapped('balance')))
|
||||
for t1, t2 in zip(sorted(manually_calculated_taxes), sorted(tax_lines.mapped('balance'))):
|
||||
self.assertAlmostEqual(t1, t2, msg='Taxes should be correctly combined.')
|
||||
|
||||
receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
self.assertAlmostEqual(receivable_line.balance, -264.76)
|
||||
|
||||
self.assertTrue(pos_receivable_line_cash.full_reconcile_id)
|
||||
self.assertTrue(receivable_line.full_reconcile_id)
|
||||
@@ -0,0 +1,170 @@
|
||||
import odoo
|
||||
from odoo.tests.common import Form
|
||||
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestPoSOtherCurrencyConfig(TestPoSCommon):
|
||||
""" Test PoS with basic configuration
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestPoSOtherCurrencyConfig, self).setUp()
|
||||
self.config = self.other_currency_config
|
||||
self.product1 = self.create_product('Product 1', self.categ_basic, 10.0, 5)
|
||||
self.product2 = self.create_product('Product 2', self.categ_basic, 20.0, 10)
|
||||
self.product3 = self.create_product('Product 3', self.categ_basic, 30.0, 15)
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [100, 50, 50])
|
||||
# change the price of product2 to 12.99 fixed. No need to convert.
|
||||
pricelist_item = self.env['product.pricelist.item'].create({
|
||||
'product_tmpl_id': self.product2.product_tmpl_id.id,
|
||||
'fixed_price': 12.99,
|
||||
})
|
||||
self.config.pricelist_id.write({'item_ids': [(6, 0, (self.config.pricelist_id.item_ids | pricelist_item).ids)]})
|
||||
|
||||
def test_01_check_product_cost(self):
|
||||
# Product price should be half of the original price because currency rate is 0.5.
|
||||
# (see `self._create_other_currency_config` method)
|
||||
# Except for product2 where the price is specified in the pricelist.
|
||||
self.assertAlmostEqual(self.config.pricelist_id.get_product_price(self.product1, 1, self.customer), 5.00)
|
||||
self.assertAlmostEqual(self.config.pricelist_id.get_product_price(self.product2, 1, self.customer), 12.99)
|
||||
self.assertAlmostEqual(self.config.pricelist_id.get_product_price(self.product3, 1, self.customer), 15.00)
|
||||
|
||||
def test_02_orders_without_invoice(self):
|
||||
""" orders without invoice
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
| order | payments | invoiced? | product | qty | total |
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
| order 1 | cash | no | product1 | 10 | 50 |
|
||||
| | | | product2 | 10 | 129.9 |
|
||||
| | | | product3 | 10 | 150 |
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
| order 2 | cash | no | product1 | 5 | 25 |
|
||||
| | | | product2 | 5 | 64.95 |
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
| order 3 | bank | no | product2 | 5 | 64.95 |
|
||||
| | | | product3 | 5 | 75 |
|
||||
+---------+----------+-----------+----------+-----+-------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+-----------------+
|
||||
| account | balance | amount_currency |
|
||||
+---------------------+---------+-----------------+
|
||||
| sale_account | -1119.6 | -559.80 |
|
||||
| pos receivable bank | 279.9 | 139.95 |
|
||||
| pos receivable cash | 839.7 | 419.85 |
|
||||
+---------------------+---------+-----------------+
|
||||
| Total balance | 0.0 | 0.00 |
|
||||
+---------------------+---------+-----------------+
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 10), (self.product3, 10)]))
|
||||
orders.append(self.create_ui_order_data([(self.product1, 5), (self.product2, 5)]))
|
||||
orders.append(self.create_ui_order_data([(self.product2, 5), (self.product3, 5)], payments=[(self.bank_pm, 139.95)]))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sale_account_line = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(sale_account_line.balance, -1119.6)
|
||||
self.assertAlmostEqual(sale_account_line.amount_currency, -559.80)
|
||||
|
||||
pos_receivable_line_bank = session_move.line_ids.filtered(lambda line: line.account_id == self.pos_receivable_account and self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(pos_receivable_line_bank.balance, 279.9)
|
||||
self.assertAlmostEqual(pos_receivable_line_bank.amount_currency, 139.95)
|
||||
|
||||
pos_receivable_line_cash = session_move.line_ids.filtered(lambda line: line.account_id == self.pos_receivable_account and self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(pos_receivable_line_cash.balance, 839.7)
|
||||
self.assertAlmostEqual(pos_receivable_line_cash.amount_currency, 419.85)
|
||||
|
||||
def test_03_orders_with_invoice(self):
|
||||
""" orders with invoice
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order | payments | invoiced? | product | qty | total |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order 1 | cash | no | product1 | 10 | 50 |
|
||||
| | | | product2 | 10 | 129.9 |
|
||||
| | | | product3 | 10 | 150 |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order 2 | cash | yes, customer | product1 | 5 | 25 |
|
||||
| | | | product2 | 5 | 64.95 |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
| order 3 | bank | yes, customer | product2 | 5 | 64.95 |
|
||||
| | | | product3 | 5 | 75 |
|
||||
+---------+----------+---------------+----------+-----+-------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+-----------------+
|
||||
| account | balance | amount_currency |
|
||||
+---------------------+---------+-----------------+
|
||||
| sale_account | -659.8 | -329.90 |
|
||||
| pos receivable bank | 279.9 | 139.95 |
|
||||
| pos receivable cash | 839.7 | 419.85 |
|
||||
| invoice receivable | -459.8 | -229.90 |
|
||||
+---------------------+---------+-----------------+
|
||||
| Total balance | 0.0 | 0.00 |
|
||||
+---------------------+---------+-----------------+
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 10), (self.product3, 10)]))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 5), (self.product2, 5)],
|
||||
customer=self.customer,
|
||||
is_invoiced=True,
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 5), (self.product3, 5)],
|
||||
payments=[(self.bank_pm, 139.95)],
|
||||
customer=self.customer,
|
||||
is_invoiced=True,
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sale_account_line = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(sale_account_line.balance, -659.8)
|
||||
self.assertAlmostEqual(sale_account_line.amount_currency, -329.9)
|
||||
|
||||
pos_receivable_line_bank = session_move.line_ids.filtered(lambda line: line.account_id == self.pos_receivable_account and self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(pos_receivable_line_bank.balance, 279.9)
|
||||
self.assertAlmostEqual(pos_receivable_line_bank.amount_currency, 139.95)
|
||||
|
||||
pos_receivable_line_cash = session_move.line_ids.filtered(lambda line: line.account_id == self.pos_receivable_account and self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(pos_receivable_line_cash.balance, 839.7)
|
||||
self.assertAlmostEqual(pos_receivable_line_cash.amount_currency, 419.85)
|
||||
|
||||
invoice_receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
self.assertAlmostEqual(invoice_receivable_line.balance, -459.8)
|
||||
self.assertAlmostEqual(invoice_receivable_line.amount_currency, -229.9)
|
||||
@@ -0,0 +1,286 @@
|
||||
import odoo
|
||||
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestPoSProductsWithTax(TestPoSCommon):
|
||||
""" Test normal configuration PoS selling products with tax
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestPoSProductsWithTax, self).setUp()
|
||||
self.config = self.basic_config
|
||||
self.product1 = self.create_product(
|
||||
'Product 1',
|
||||
self.categ_basic,
|
||||
10.0,
|
||||
5.0,
|
||||
tax_ids=self.taxes['tax7'].ids,
|
||||
)
|
||||
self.product2 = self.create_product(
|
||||
'Product 2',
|
||||
self.categ_basic,
|
||||
20.0,
|
||||
10.0,
|
||||
tax_ids=self.taxes['tax10'].ids,
|
||||
)
|
||||
self.product3 = self.create_product(
|
||||
'Product 3',
|
||||
self.categ_basic,
|
||||
30.0,
|
||||
15.0,
|
||||
tax_ids=self.taxes['tax_group_7_10'].ids,
|
||||
)
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [100, 50, 50])
|
||||
|
||||
def test_orders_no_invoiced(self):
|
||||
""" Test for orders without invoice
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+-----------+----------+-----+---------+-----------------------+--------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+---------+----------+-----------+----------+-----+---------+-----------------------+--------+
|
||||
| order 1 | cash | no | product1 | 10 | 100 | 7 | 107 |
|
||||
| | | | product2 | 5 | 90.91 | 9.09 | 100 |
|
||||
+---------+----------+-----------+----------+-----+---------+-----------------------+--------+
|
||||
| order 2 | cash | no | product2 | 7 | 127.27 | 12.73 | 140 |
|
||||
| | | | product3 | 4 | 109.09 | 10.91[10%] + 7.64[7%] | 127.64 |
|
||||
+---------+----------+-----------+----------+-----+---------+-----------------------+--------+
|
||||
| order 3 | bank | no | product1 | 1 | 10 | 0.7 | 10.7 |
|
||||
| | | | product2 | 3 | 54.55 | 5.45 | 60 |
|
||||
| | | | product3 | 5 | 136.36 | 13.64[10%] + 9.55[7%] | 159.55 |
|
||||
+---------+----------+-----------+----------+-----+---------+-----------------------+--------+
|
||||
|
||||
Calculated taxes
|
||||
================
|
||||
total tax 7% only + group tax (10+7%)
|
||||
(7 + 0.7) + (7.64 + 9.55) = 7.7 + 17.19 = 24.89
|
||||
total tax 10% only + group tax (10+7%)
|
||||
(9.09 + 12.73 + 5.45) + (10.91 + 13.64) = 27.27 + 24.55 = 51.82
|
||||
|
||||
Thus, manually_calculated_taxes = (-24,89, -51.82)
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 5)]))
|
||||
orders.append(self.create_ui_order_data([(self.product2, 7), (self.product3, 4)]))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 1), (self.product3, 5), (self.product2, 3)],
|
||||
payments=[(self.bank_pm, 230.25)]
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, 'Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sales_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(sum(sales_lines.mapped('balance')), -628.18, msg='Sales line balance should be equal to untaxed orders amount.')
|
||||
|
||||
receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_bank.balance, 230.25, msg='Bank receivable should be equal to the total bank payments.')
|
||||
|
||||
receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_cash.balance, 474.64, msg='Cash receivable should be equal to the total cash payments.')
|
||||
|
||||
tax_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.tax_received_account)
|
||||
|
||||
manually_calculated_taxes = (-24.89, -51.82)
|
||||
self.assertAlmostEqual(sum(manually_calculated_taxes), sum(tax_lines.mapped('balance')))
|
||||
for t1, t2 in zip(sorted(manually_calculated_taxes), sorted(tax_lines.mapped('balance'))):
|
||||
self.assertAlmostEqual(t1, t2, msg='Taxes should be correctly combined.')
|
||||
|
||||
base_amounts = (355.45, 518.18)
|
||||
self.assertAlmostEqual(sum(base_amounts), sum(tax_lines.mapped('tax_base_amount')))
|
||||
|
||||
self.assertTrue(receivable_line_cash.full_reconcile_id, 'Cash receivable line should be fully-reconciled.')
|
||||
|
||||
def test_orders_with_invoiced(self):
|
||||
""" Test for orders: one with invoice
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+---------------+----------+-----+---------+---------------+--------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+---------+----------+---------------+----------+-----+---------+---------------+--------+
|
||||
| order 1 | cash | no | product1 | 6 | 60 | 4.2 | 64.2 |
|
||||
| | | | product2 | 3 | 54.55 | 5.45 | 60 |
|
||||
| | | | product3 | 1 | 27.27 | 2.73 + 1.91 | 31.91 |
|
||||
+---------+----------+---------------+----------+-----+---------+---------------+--------+
|
||||
| order 2 | bank | no | product1 | 1 | 10 | 0.7 | 10.7 |
|
||||
| | | | product2 | 20 | 363.64 | 36.36 | 400 |
|
||||
+---------+----------+---------------+----------+-----+---------+---------------+--------+
|
||||
| order 3 | bank | yes, customer | product1 | 10 | 100 | 7 | 107 |
|
||||
| | | | product3 | 10 | 272.73 | 27.27 + 19.09 | 319.09 |
|
||||
+---------+----------+---------------+----------+-----+---------+---------------+--------+
|
||||
|
||||
Calculated taxes
|
||||
================
|
||||
total tax 7% only
|
||||
4.2 + 0.7 => 4.9 + 1.91 = 6.81
|
||||
total tax 10% only
|
||||
5.45 + 36.36 => 41.81 + 2.73 = 44.54
|
||||
|
||||
Thus, manually_calculated_taxes = (-6.81, -44.54)
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product3, 1), (self.product1, 6), (self.product2, 3)],
|
||||
payments=[(self.cash_pm, 156.11)],
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 20), (self.product1, 1)],
|
||||
payments=[(self.bank_pm, 410.7)],
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 10), (self.product3, 10)],
|
||||
payments=[(self.bank_pm, 426.09)],
|
||||
customer=self.customer,
|
||||
is_invoiced=True,
|
||||
uid='09876-098-0987',
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# check account move in the invoiced order
|
||||
invoiced_order = self.pos_session.order_ids.filtered(lambda order: '09876-098-0987' in order.pos_reference)
|
||||
self.assertEqual(1, len(invoiced_order), 'Only one order is invoiced in this test.')
|
||||
invoice = invoiced_order.account_move
|
||||
self.assertAlmostEqual(invoice.amount_total, 426.09)
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
# check sales line
|
||||
# should not include tax amounts
|
||||
sales_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(sum(sales_lines.mapped('balance')), -515.46)
|
||||
|
||||
# check receivable line
|
||||
# should be equivalent to receivable in the invoice
|
||||
# should also be fully-reconciled
|
||||
receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
self.assertAlmostEqual(receivable_line.balance, -426.09)
|
||||
self.assertTrue(receivable_line.full_reconcile_id, msg='Receivable line for invoices should be fully reconciled.')
|
||||
|
||||
pos_receivable_line_bank = session_move.line_ids.filtered(
|
||||
lambda line: self.bank_pm.name in line.name and line.account_id == self.bank_pm.receivable_account_id
|
||||
)
|
||||
self.assertAlmostEqual(pos_receivable_line_bank.balance, 836.79)
|
||||
|
||||
pos_receivable_line_cash = session_move.line_ids.filtered(
|
||||
lambda line: self.cash_pm.name in line.name and line.account_id == self.bank_pm.receivable_account_id
|
||||
)
|
||||
self.assertAlmostEqual(pos_receivable_line_cash.balance, 156.11)
|
||||
self.assertTrue(pos_receivable_line_cash.full_reconcile_id)
|
||||
|
||||
receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
self.assertAlmostEqual(receivable_line.balance, -invoice.amount_total)
|
||||
|
||||
tax_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.tax_received_account)
|
||||
|
||||
manually_calculated_taxes = (-6.81, -44.54)
|
||||
self.assertAlmostEqual(sum(manually_calculated_taxes), sum(tax_lines.mapped('balance')))
|
||||
for t1, t2 in zip(sorted(manually_calculated_taxes), sorted(tax_lines.mapped('balance'))):
|
||||
self.assertAlmostEqual(t1, t2, msg='Taxes should be correctly combined.')
|
||||
|
||||
base_amounts = (97.27, 445.46) # computation does not include invoiced order.
|
||||
self.assertAlmostEqual(sum(base_amounts), sum(tax_lines.mapped('tax_base_amount')))
|
||||
|
||||
def test_return_order(self):
|
||||
""" Test return order
|
||||
|
||||
Order (invoiced)
|
||||
======
|
||||
+----------+----------+---------------+----------+-----+---------+-------------+-------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+----------+----------+---------------+----------+-----+---------+-------------+-------+
|
||||
| order 1 | cash | yes, customer | product1 | 3 | 30 | 2.1 | 32.1 |
|
||||
| | | | product2 | 2 | 36.36 | 3.64 | 40 |
|
||||
| | | | product3 | 1 | 27.27 | 2.73 + 1.91 | 31.91 |
|
||||
+----------+----------+---------------+----------+-----+---------+-------------+-------+
|
||||
|
||||
The order is invoiced so the tax of the invoiced order is in the account_move of the order.
|
||||
However, the return order is not invoiced, thus, the journal items are in the session_move,
|
||||
which will contain the tax lines of the returned products.
|
||||
|
||||
manually_calculated_taxes = (4.01, 6.37)
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 3), (self.product2, 2), (self.product3, 1)],
|
||||
payments=[(self.cash_pm, 104.01)],
|
||||
customer=self.customer,
|
||||
is_invoiced=True,
|
||||
uid='12345-123-1234',
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(1, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# return order
|
||||
order_to_return = self.pos_session.order_ids.filtered(lambda order: '12345-123-1234' in order.pos_reference)
|
||||
order_to_return.refund()
|
||||
|
||||
refund_order = self.pos_session.order_ids.filtered(lambda order: order.state == 'draft')
|
||||
context_make_payment = {"active_ids": [refund_order.id], "active_id": refund_order.id}
|
||||
make_payment = self.env['pos.make.payment'].with_context(context_make_payment).create({
|
||||
'payment_method_id': self.cash_pm.id,
|
||||
'amount': -104.01,
|
||||
})
|
||||
make_payment.check()
|
||||
self.assertEqual(refund_order.state, 'paid', 'Payment is registered, order should be paid.')
|
||||
self.assertAlmostEqual(refund_order.amount_paid, -104.01, msg='Amount paid for return order should be negative.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
# instead of credit, the sales line should be debit
|
||||
sales_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(sum(sales_lines.mapped('balance')), 93.63)
|
||||
|
||||
receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertFalse(receivable_line_bank, msg='There should be no bank receivable line because no bank payment made.')
|
||||
|
||||
receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertFalse(receivable_line_cash, msg='There should be no cash receivable line because it is combined with the original cash payment.')
|
||||
|
||||
manually_calculated_taxes = (4.01, 6.37) # should be positive since it is return order
|
||||
tax_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.tax_received_account)
|
||||
self.assertAlmostEqual(sum(manually_calculated_taxes), sum(tax_lines.mapped('balance')))
|
||||
for t1, t2 in zip(sorted(manually_calculated_taxes), sorted(tax_lines.mapped('balance'))):
|
||||
self.assertAlmostEqual(t1, t2, msg='Taxes should be correctly combined and should be debit.')
|
||||
@@ -0,0 +1,69 @@
|
||||
import odoo
|
||||
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestPoSSetup(TestPoSCommon):
|
||||
""" This group of tests is for sanity check in setting up global records which will be used
|
||||
in each testing.
|
||||
|
||||
If a test fails here, then it means there are inconsistencies in what we expect in the setup.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestPoSSetup, self).setUp()
|
||||
self.config = self.basic_config
|
||||
self.products = [
|
||||
self.create_product('Product 1', self.categ_basic, lst_price=10.0, standard_price=5),
|
||||
self.create_product('Product 2', self.categ_basic, lst_price=20.0, standard_price=10),
|
||||
self.create_product('Product 3', self.categ_basic, lst_price=30.0, standard_price=15),
|
||||
]
|
||||
|
||||
def test_basic_config_values(self):
|
||||
config = self.basic_config
|
||||
self.assertEqual(config.currency_id, self.company_currency)
|
||||
self.assertEqual(config.pricelist_id.currency_id, self.company_currency)
|
||||
|
||||
def test_other_currency_config_values(self):
|
||||
config = self.other_currency_config
|
||||
self.assertEqual(config.currency_id, self.other_currency)
|
||||
self.assertEqual(config.pricelist_id.currency_id, self.other_currency)
|
||||
|
||||
def test_product_categories(self):
|
||||
# check basic product category
|
||||
# it is expected to have standard and manual_periodic valuation
|
||||
self.assertEqual(self.categ_basic.property_cost_method, 'standard')
|
||||
self.assertEqual(self.categ_basic.property_valuation, 'manual_periodic')
|
||||
# check anglo saxon product category
|
||||
# this product categ is expected to have fifo and real_time valuation
|
||||
self.assertEqual(self.categ_anglo.property_cost_method, 'fifo')
|
||||
self.assertEqual(self.categ_anglo.property_valuation, 'real_time')
|
||||
|
||||
def test_product_price(self):
|
||||
def get_price(pricelist, product):
|
||||
return pricelist.get_product_price(product, 1, self.customer)
|
||||
|
||||
# check usd pricelist
|
||||
pricelist = self.basic_config.pricelist_id
|
||||
for product in self.products:
|
||||
self.assertAlmostEqual(get_price(pricelist, product), product.lst_price)
|
||||
|
||||
# check eur pricelist
|
||||
# exchange rate to the other currency is set to 0.5, thus, lst_price
|
||||
# is expected to have half its original value.
|
||||
pricelist = self.other_currency_config.pricelist_id
|
||||
for product in self.products:
|
||||
self.assertAlmostEqual(get_price(pricelist, product), product.lst_price * 0.5)
|
||||
|
||||
def test_taxes(self):
|
||||
tax7 = self.taxes['tax7']
|
||||
self.assertEqual(tax7.name, 'Tax 7%')
|
||||
self.assertAlmostEqual(tax7.amount, 7)
|
||||
self.assertEqual(tax7.invoice_repartition_line_ids.mapped('account_id').id, self.tax_received_account.id)
|
||||
tax10 = self.taxes['tax10']
|
||||
self.assertEqual(tax10.name, 'Tax 10%')
|
||||
self.assertAlmostEqual(tax10.amount, 10)
|
||||
self.assertEqual(tax10.price_include, True)
|
||||
self.assertEqual(tax10.invoice_repartition_line_ids.mapped('account_id').id, self.tax_received_account.id)
|
||||
tax_group_7_10 = self.taxes['tax_group_7_10']
|
||||
self.assertEqual(tax_group_7_10.name, 'Tax 7+10%')
|
||||
self.assertEqual(tax_group_7_10.amount_type, 'group')
|
||||
self.assertEqual(sorted(tax_group_7_10.children_tax_ids.ids), sorted((tax7 | tax10).ids))
|
||||
@@ -0,0 +1,194 @@
|
||||
import odoo
|
||||
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestPoSStock(TestPoSCommon):
|
||||
""" Tests for anglo saxon accounting scenario.
|
||||
"""
|
||||
def setUp(self):
|
||||
super(TestPoSStock, self).setUp()
|
||||
self.config = self.basic_config
|
||||
self.product1 = self.create_product('Product 1', self.categ_anglo, 10.0, 5.0)
|
||||
self.product2 = self.create_product('Product 2', self.categ_anglo, 20.0, 10.0)
|
||||
self.product3 = self.create_product('Product 3', self.categ_basic, 30.0, 15.0)
|
||||
# start inventory with 10 items for each product
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [10, 10, 10])
|
||||
|
||||
# change cost(standard_price) of anglo products
|
||||
# then set inventory from 10 -> 15
|
||||
self.product1.write({'standard_price': 6.0})
|
||||
self.product2.write({'standard_price': 6.0})
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [15, 15, 15])
|
||||
|
||||
# change cost(standard_price) of anglo products
|
||||
# then set inventory from 15 -> 25
|
||||
self.product1.write({'standard_price': 13.0})
|
||||
self.product2.write({'standard_price': 13.0})
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [25, 25, 25])
|
||||
|
||||
self.output_account = self.categ_anglo.property_stock_account_output_categ_id
|
||||
self.expense_account = self.categ_anglo.property_account_expense_categ_id
|
||||
self.valuation_account = self.categ_anglo.property_stock_valuation_account_id
|
||||
|
||||
def test_01_orders_no_invoiced(self):
|
||||
"""
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+-----+-------------+------------+
|
||||
| order | product | qty | total price | total cost |
|
||||
+---------+----------+-----+-------------+------------+
|
||||
| order 1 | product1 | 10 | 100.0 | 50.0 | -> 10 items at cost of 5.0 is consumed, remains 5 items at 6.0 and 10 items at 13.0
|
||||
| | product2 | 10 | 200.0 | 100.0 | -> 10 items at cost of 10.0 is consumed, remains 5 items at 6.0 and 10 items at 13.0
|
||||
+---------+----------+-----+-------------+------------+
|
||||
| order 2 | product2 | 7 | 140.0 | 56.0 | -> 5 items at cost of 6.0 and 2 items at cost of 13.0, remains 8 items at cost of 13.0
|
||||
| | product3 | 7 | 210.0 | 0.0 |
|
||||
+---------+----------+-----+-------------+------------+
|
||||
| order 3 | product1 | 6 | 60.0 | 43.0 | -> 5 items at cost of 6.0 and 1 item at cost of 13.0, remains 9 items at cost of 13.0
|
||||
| | product2 | 6 | 120.0 | 78.0 | -> 6 items at cost of 13.0, remains 2 items at cost of 13.0
|
||||
| | product3 | 6 | 180.0 | 0.0 |
|
||||
+---------+----------+-----+-------------+------------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale_account | -1010.0 |
|
||||
| pos_receivable-cash | 1010.0 |
|
||||
| expense_account | 327.0 |
|
||||
| output_account | -327.0 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.00 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 10)]))
|
||||
orders.append(self.create_ui_order_data([(self.product2, 7), (self.product3, 7)]))
|
||||
orders.append(self.create_ui_order_data([(self.product1, 6), (self.product2, 6), (self.product3, 6)]))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
self.assertAlmostEqual(orders_total, 1010.0, msg='The orders\'s total amount should equal the computed.')
|
||||
|
||||
# check product qty_available after syncing the order
|
||||
self.assertEqual(self.product1.qty_available, 9)
|
||||
self.assertEqual(self.product2.qty_available, 2)
|
||||
self.assertEqual(self.product3.qty_available, 12)
|
||||
|
||||
# picking and stock moves should be in done state
|
||||
for order in self.pos_session.order_ids:
|
||||
self.assertEqual(order.picking_id.state, 'done', 'Picking should be in done state.')
|
||||
self.assertTrue(all(state == 'done' for state in order.picking_id.move_lines.mapped('state')), 'Move Lines should be in done state.' )
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
account_move = self.pos_session.move_id
|
||||
|
||||
sales_line = account_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(sales_line.balance, -orders_total, msg='Sales line balance should be equal to total orders amount.')
|
||||
|
||||
receivable_line_cash = account_move.line_ids.filtered(lambda line: self.pos_receivable_account == line.account_id and self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_cash.balance, 1010.0, msg='Cash receivable should be equal to the total cash payments.')
|
||||
|
||||
expense_line = account_move.line_ids.filtered(lambda line: line.account_id == self.expense_account)
|
||||
self.assertAlmostEqual(expense_line.balance, 327.0)
|
||||
|
||||
output_line = account_move.line_ids.filtered(lambda line: line.account_id == self.output_account)
|
||||
self.assertAlmostEqual(output_line.balance, -327.0)
|
||||
|
||||
self.assertTrue(receivable_line_cash.full_reconcile_id, msg='Cash receivable line should be fully-reconciled.')
|
||||
self.assertTrue(output_line.full_reconcile_id, msg='The stock output account line should be fully-reconciled.')
|
||||
|
||||
def test_02_orders_with_invoice(self):
|
||||
"""
|
||||
|
||||
Orders
|
||||
======
|
||||
Same with test_01 but order 3 is invoiced.
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale_account | -650.0 |
|
||||
| pos_receivable-cash | 1010.0 |
|
||||
| receivable | -360.0 |
|
||||
| expense_account | 206.0 |
|
||||
| output_account | -206.0 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.00 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data([(self.product1, 10), (self.product2, 10)]))
|
||||
orders.append(self.create_ui_order_data([(self.product2, 7), (self.product3, 7)]))
|
||||
invoiced_uid = self.create_random_uid()
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 6), (self.product2, 6), (self.product3, 6)],
|
||||
is_invoiced=True,
|
||||
customer=self.customer,
|
||||
uid=invoiced_uid,
|
||||
))
|
||||
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
self.assertAlmostEqual(orders_total, 1010.0, msg='The orders\'s total amount should equal the computed.')
|
||||
|
||||
# check product qty_available after syncing the order
|
||||
self.assertEqual(self.product1.qty_available, 9)
|
||||
self.assertEqual(self.product2.qty_available, 2)
|
||||
self.assertEqual(self.product3.qty_available, 12)
|
||||
|
||||
# picking and stock moves should be in done state
|
||||
for order in self.pos_session.order_ids:
|
||||
self.assertEqual(order.picking_id.state, 'done', 'Picking should be in done state.')
|
||||
self.assertTrue(all(state == 'done' for state in order.picking_id.move_lines.mapped('state')), 'Move Lines should be in done state.' )
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
account_move = self.pos_session.move_id
|
||||
|
||||
sales_line = account_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertAlmostEqual(sales_line.balance, -650.0)
|
||||
|
||||
receivable_line = account_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
self.assertAlmostEqual(receivable_line.balance, -360.0, msg='Receivable line balance should equal the negative of total amount of invoiced orders.')
|
||||
|
||||
receivable_line_cash = account_move.line_ids.filtered(lambda line: self.pos_receivable_account == line.account_id and self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_cash.balance, 1010.0, msg='Cash receivable should be equal to the total cash payments.')
|
||||
|
||||
expense_line = account_move.line_ids.filtered(lambda line: line.account_id == self.expense_account)
|
||||
self.assertAlmostEqual(expense_line.balance, 206.0)
|
||||
|
||||
output_line = account_move.line_ids.filtered(lambda line: line.account_id == self.output_account)
|
||||
self.assertAlmostEqual(output_line.balance, -206.0)
|
||||
|
||||
# check order journal entry
|
||||
invoiced_order = self.pos_session.order_ids.filtered(lambda order: invoiced_uid in order.pos_reference)
|
||||
invoiced_output_account_lines = invoiced_order.account_move.line_ids.filtered(lambda line: line.account_id == self.output_account)
|
||||
self.assertAlmostEqual(sum(invoiced_output_account_lines.mapped('balance')), -121.0)
|
||||
|
||||
self.assertTrue(receivable_line_cash.full_reconcile_id, msg='Cash receivable line should be fully-reconciled.')
|
||||
self.assertTrue(output_line.full_reconcile_id, msg='The stock output account line should be fully-reconciled.')
|
||||
@@ -0,0 +1,379 @@
|
||||
import odoo
|
||||
from odoo.addons.point_of_sale.tests.common import TestPoSCommon
|
||||
|
||||
@odoo.tests.tagged('post_install', '-at_install')
|
||||
class TestPoSWithFiscalPosition(TestPoSCommon):
|
||||
""" Tests to pos orders with fiscal position.
|
||||
|
||||
keywords/phrases: fiscal position
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(TestPoSWithFiscalPosition, self).setUp()
|
||||
self.config = self.basic_config
|
||||
|
||||
self.new_tax_17 = self.env['account.tax'].create({'name': 'New Tax 17%', 'amount': 17})
|
||||
self.new_tax_17.invoice_repartition_line_ids.write({'account_id': self.tax_received_account.id})
|
||||
|
||||
self.fpos = self._create_fiscal_position()
|
||||
self.fpos_no_tax_dest = self._create_fiscal_position_no_tax_dest()
|
||||
|
||||
self.product1 = self.create_product(
|
||||
'Product 1',
|
||||
self.categ_basic,
|
||||
lst_price=10.99,
|
||||
standard_price=5.0,
|
||||
tax_ids=self.taxes['tax7'].ids,
|
||||
)
|
||||
self.product2 = self.create_product(
|
||||
'Product 2',
|
||||
self.categ_basic,
|
||||
lst_price=19.99,
|
||||
standard_price=10.0,
|
||||
tax_ids=self.taxes['tax10'].ids,
|
||||
)
|
||||
self.product3 = self.create_product(
|
||||
'Product 3',
|
||||
self.categ_basic,
|
||||
lst_price=30.99,
|
||||
standard_price=15.0,
|
||||
tax_ids=self.taxes['tax7'].ids,
|
||||
)
|
||||
self.adjust_inventory([self.product1, self.product2, self.product3], [100, 50, 50])
|
||||
|
||||
def _create_fiscal_position(self):
|
||||
fpos = self.env['account.fiscal.position'].create({'name': 'Test Fiscal Position'})
|
||||
|
||||
account_fpos = self.env['account.fiscal.position.account'].create({
|
||||
'position_id': fpos.id,
|
||||
'account_src_id': self.sale_account.id,
|
||||
'account_dest_id': self.other_sale_account.id,
|
||||
})
|
||||
tax_fpos = self.env['account.fiscal.position.tax'].create({
|
||||
'position_id': fpos.id,
|
||||
'tax_src_id': self.taxes['tax7'].id,
|
||||
'tax_dest_id': self.new_tax_17.id,
|
||||
})
|
||||
fpos.write({
|
||||
'account_ids': [(6, 0, account_fpos.ids)],
|
||||
'tax_ids': [(6, 0, tax_fpos.ids)],
|
||||
})
|
||||
return fpos
|
||||
|
||||
def _create_fiscal_position_no_tax_dest(self):
|
||||
fpos_no_tax_dest = self.env['account.fiscal.position'].create({'name': 'Test Fiscal Position'})
|
||||
account_fpos = self.env['account.fiscal.position.account'].create({
|
||||
'position_id': fpos_no_tax_dest.id,
|
||||
'account_src_id': self.sale_account.id,
|
||||
'account_dest_id': self.other_sale_account.id,
|
||||
})
|
||||
tax_fpos = self.env['account.fiscal.position.tax'].create({
|
||||
'position_id': fpos_no_tax_dest.id,
|
||||
'tax_src_id': self.taxes['tax7'].id,
|
||||
})
|
||||
fpos_no_tax_dest.write({
|
||||
'account_ids': [(6, 0, account_fpos.ids)],
|
||||
'tax_ids': [(6, 0, tax_fpos.ids)],
|
||||
})
|
||||
return fpos_no_tax_dest
|
||||
|
||||
def test_01_no_invoice_fpos(self):
|
||||
""" orders without invoice
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+---------------+----------+-----+---------+-----------------+--------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+---------+----------+---------------+----------+-----+---------+-----------------+--------+
|
||||
| order 1 | cash | yes, customer | product1 | 10 | 109.90 | 18.68 [7%->17%] | 128.58 |
|
||||
| | | | product2 | 10 | 181.73 | 18.17 [10%] | 199.90 |
|
||||
| | | | product3 | 10 | 309.90 | 52.68 [7%->17%] | 362.58 |
|
||||
+---------+----------+---------------+----------+-----+---------+-----------------+--------+
|
||||
| order 2 | cash | yes, customer | product1 | 5 | 54.95 | 9.34 [7%->17%] | 64.29 |
|
||||
| | | | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
+---------+----------+---------------+----------+-----+---------+-----------------+--------+
|
||||
| order 3 | bank | no | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
| | | | product3 | 5 | 154.95 | 10.85 [7%] | 165.8 |
|
||||
+---------+----------+---------------+----------+-----+---------+-----------------+--------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale_account | -154.95 | (for the 7% base amount)
|
||||
| sale_account | -90.86 | (for the 10% base amount)
|
||||
| other_sale_account | -474.75 | (for the 17% base amount)
|
||||
| other_sale_account | -272.59 | (for the 10% base amount)
|
||||
| tax 17% | -80.70 |
|
||||
| tax 10% | -36.35 |
|
||||
| tax 7% | -10.85 |
|
||||
| pos receivable bank | 265.75 |
|
||||
| pos receivable cash | 855.30 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.0 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
self.customer.write({'property_account_position_id': self.fpos.id})
|
||||
self.open_new_session()
|
||||
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 10), (self.product2, 10), (self.product3, 10)],
|
||||
customer=self.customer
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 5), (self.product2, 5)],
|
||||
customer=self.customer,
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 5), (self.product3, 5)],
|
||||
payments=[(self.bank_pm, 265.75)],
|
||||
))
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sale_account_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
lines_balance = [-154.95, -90.86]
|
||||
self.assertEqual(len(sale_account_lines), len(lines_balance))
|
||||
for balance, amount in zip(sorted(sale_account_lines.mapped('balance')), sorted(lines_balance)):
|
||||
self.assertAlmostEqual(balance, amount)
|
||||
|
||||
other_sale_account_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.other_sale_account)
|
||||
lines_balance = [-474.75, -272.59]
|
||||
self.assertEqual(len(other_sale_account_lines), len(lines_balance))
|
||||
for balance, amount in zip(sorted(other_sale_account_lines.mapped('balance')), sorted(lines_balance)):
|
||||
self.assertAlmostEqual(balance, amount)
|
||||
|
||||
receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_bank.balance, 265.75)
|
||||
|
||||
receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_cash.balance, 855.3)
|
||||
|
||||
manually_calculated_taxes = (-80.7, -36.35, -10.85)
|
||||
tax_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.tax_received_account)
|
||||
self.assertAlmostEqual(len(manually_calculated_taxes), len(tax_lines.mapped('balance')))
|
||||
for t1, t2 in zip(sorted(manually_calculated_taxes), sorted(tax_lines.mapped('balance'))):
|
||||
self.assertAlmostEqual(t1, t2, msg='Taxes should be correctly combined.')
|
||||
|
||||
self.assertTrue(receivable_line_cash.full_reconcile_id)
|
||||
|
||||
def test_02_no_invoice_fpos_no_tax_dest(self):
|
||||
""" Customer with fiscal position that maps a tax to no tax.
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+---------------+----------+-----+---------+-------------+--------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+---------+----------+---------------+----------+-----+---------+-------------+--------+
|
||||
| order 1 | bank | yes, customer | product1 | 10 | 109.90 | 0 | 109.90 |
|
||||
| | | | product2 | 10 | 181.73 | 18.17 [10%] | 199.90 |
|
||||
| | | | product3 | 10 | 309.90 | 0 | 309.90 |
|
||||
+---------+----------+---------------+----------+-----+---------+-------------+--------+
|
||||
| order 2 | cash | yes, customer | product1 | 5 | 54.95 | 0 | 54.95 |
|
||||
| | | | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
+---------+----------+---------------+----------+-----+---------+-------------+--------+
|
||||
| order 3 | bank | no | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
| | | | product3 | 5 | 154.95 | 10.85 [7%] | 165.80 |
|
||||
+---------+----------+---------------+----------+-----+---------+-------------+--------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| sale_account | -154.95 | (for the 7% base amount)
|
||||
| sale_account | -90.86 | (for the 10% base amount)
|
||||
| other_sale_account | -272.59 | (for the 10% base amount)
|
||||
| other_sale_account | -474.75 | (no tax)
|
||||
| tax 10% | -36.35 |
|
||||
| tax 7% | -10.85 |
|
||||
| pos receivable bank | 885.45 |
|
||||
| pos receivable cash | 154.9 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.0 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
self.customer.write({'property_account_position_id': self.fpos_no_tax_dest.id})
|
||||
self.open_new_session()
|
||||
# create orders
|
||||
orders = []
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 10), (self.product2, 10), (self.product3, 10)],
|
||||
customer=self.customer,
|
||||
payments=[(self.bank_pm, 619.7)],
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 5), (self.product2, 5)],
|
||||
customer=self.customer,
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 5), (self.product3, 5)],
|
||||
payments=[(self.bank_pm, 265.75)],
|
||||
))
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sale_account_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
lines_balance = [-154.95, -90.86]
|
||||
self.assertEqual(len(sale_account_lines), len(lines_balance))
|
||||
for balance, amount in zip(sorted(sale_account_lines.mapped('balance')), sorted(lines_balance)):
|
||||
self.assertAlmostEqual(balance, amount)
|
||||
|
||||
other_sale_account_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.other_sale_account)
|
||||
lines_balance = [-474.75, -272.59]
|
||||
self.assertEqual(len(other_sale_account_lines), len(lines_balance))
|
||||
for balance, amount in zip(sorted(other_sale_account_lines.mapped('balance')), sorted(lines_balance)):
|
||||
self.assertAlmostEqual(balance, amount)
|
||||
|
||||
receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_bank.balance, 885.45)
|
||||
|
||||
receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_cash.balance, 154.9)
|
||||
|
||||
manually_calculated_taxes = [-36.35, -10.85]
|
||||
tax_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.tax_received_account)
|
||||
self.assertAlmostEqual(len(manually_calculated_taxes), len(tax_lines.mapped('balance')))
|
||||
for t1, t2 in zip(sorted(manually_calculated_taxes), sorted(tax_lines.mapped('balance'))):
|
||||
self.assertAlmostEqual(t1, t2, msg='Taxes should be correctly combined.')
|
||||
|
||||
self.assertTrue(receivable_line_cash.full_reconcile_id)
|
||||
|
||||
def test_03_invoiced_fpos(self):
|
||||
""" Invoice 2 orders.
|
||||
|
||||
Orders
|
||||
======
|
||||
+---------+----------+---------------------+----------+-----+---------+-----------------+--------+
|
||||
| order | payments | invoiced? | product | qty | untaxed | tax | total |
|
||||
+---------+----------+---------------------+----------+-----+---------+-----------------+--------+
|
||||
| order 1 | bank | yes, customer | product1 | 10 | 109.90 | 18.68 [7%->17%] | 128.58 |
|
||||
| | | | product2 | 10 | 181.73 | 18.17 [10%] | 199.90 |
|
||||
| | | | product3 | 10 | 309.90 | 52.68 [7%->17%] | 362.58 |
|
||||
+---------+----------+---------------------+----------+-----+---------+-----------------+--------+
|
||||
| order 2 | cash | no, customer | product1 | 5 | 54.95 | 9.34 [7%->17%] | 64.29 |
|
||||
| | | | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
+---------+----------+---------------------+----------+-----+---------+-----------------+--------+
|
||||
| order 3 | cash | yes, other_customer | product2 | 5 | 90.86 | 9.09 [10%] | 99.95 |
|
||||
| | | | product3 | 5 | 154.95 | 10.85 [7%] | 165.80 |
|
||||
+---------+----------+---------------------+----------+-----+---------+-----------------+--------+
|
||||
|
||||
Expected Result
|
||||
===============
|
||||
+---------------------+---------+
|
||||
| account | balance |
|
||||
+---------------------+---------+
|
||||
| other_sale_account | -54.95 | (for the 17% base amount)
|
||||
| other_sale_account | -90.86 | (for the 10% base amount)
|
||||
| tax 10% | -9.09 |
|
||||
| tax 17% | -9.34 |
|
||||
| pos receivable cash | 429.99 |
|
||||
| pos receivable bank | 691.06 |
|
||||
| receivable | -691.06 |
|
||||
| other receivable | -265.75 |
|
||||
+---------------------+---------+
|
||||
| Total balance | 0.0 |
|
||||
+---------------------+---------+
|
||||
"""
|
||||
self.customer.write({'property_account_position_id': self.fpos.id})
|
||||
self.open_new_session()
|
||||
# create orders
|
||||
orders = []
|
||||
uid1 = self.create_random_uid()
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 10), (self.product2, 10), (self.product3, 10)],
|
||||
customer=self.customer,
|
||||
payments=[(self.bank_pm, 691.06)],
|
||||
is_invoiced=True,
|
||||
uid=uid1
|
||||
))
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product1, 5), (self.product2, 5)],
|
||||
customer=self.customer,
|
||||
))
|
||||
uid2 = self.create_random_uid()
|
||||
orders.append(self.create_ui_order_data(
|
||||
[(self.product2, 5), (self.product3, 5)],
|
||||
customer=self.other_customer,
|
||||
is_invoiced=True,
|
||||
uid=uid2,
|
||||
))
|
||||
# sync orders
|
||||
order = self.env['pos.order'].create_from_ui(orders)
|
||||
|
||||
# check values before closing the session
|
||||
self.assertEqual(3, self.pos_session.order_count)
|
||||
orders_total = sum(order.amount_total for order in self.pos_session.order_ids)
|
||||
self.assertAlmostEqual(orders_total, self.pos_session.total_payments_amount, msg='Total order amount should be equal to the total payment amount.')
|
||||
|
||||
invoiced_order_1 = self.pos_session.order_ids.filtered(lambda order: uid1 in order.pos_reference)
|
||||
invoiced_order_2 = self.pos_session.order_ids.filtered(lambda order: uid2 in order.pos_reference)
|
||||
|
||||
self.assertTrue(invoiced_order_1, msg='Invoiced order 1 should exist.')
|
||||
self.assertTrue(invoiced_order_2, msg='Invoiced order 2 should exist.')
|
||||
self.assertTrue(invoiced_order_1.account_move, msg='Invoiced order 1 should have invoice (account_move).')
|
||||
self.assertTrue(invoiced_order_2.account_move, msg='Invoiced order 2 should have invoice (account_move).')
|
||||
|
||||
# NOTE Tests of values in the invoice accounting lines is not done here.
|
||||
|
||||
# close the session
|
||||
self.pos_session.action_pos_session_validate()
|
||||
|
||||
# check values after the session is closed
|
||||
session_move = self.pos_session.move_id
|
||||
|
||||
sale_account_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.sale_account)
|
||||
self.assertFalse(sale_account_lines, msg='There should be no self.sale_account lines.')
|
||||
|
||||
other_sale_account_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.other_sale_account)
|
||||
lines_balance = [-54.95, -90.86]
|
||||
self.assertEqual(len(other_sale_account_lines), len(lines_balance))
|
||||
for balance, amount in zip(sorted(other_sale_account_lines.mapped('balance')), sorted(lines_balance)):
|
||||
self.assertAlmostEqual(balance, amount)
|
||||
|
||||
receivable_line_bank = session_move.line_ids.filtered(lambda line: self.bank_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_bank.balance, 691.06)
|
||||
|
||||
receivable_line_cash = session_move.line_ids.filtered(lambda line: self.cash_pm.name in line.name)
|
||||
self.assertAlmostEqual(receivable_line_cash.balance, 429.99)
|
||||
|
||||
manually_calculated_taxes = [-9.09, -9.34]
|
||||
tax_lines = session_move.line_ids.filtered(lambda line: line.account_id == self.tax_received_account)
|
||||
self.assertAlmostEqual(len(manually_calculated_taxes), len(tax_lines.mapped('balance')))
|
||||
for t1, t2 in zip(sorted(manually_calculated_taxes), sorted(tax_lines.mapped('balance'))):
|
||||
self.assertAlmostEqual(t1, t2, msg='Taxes should be correctly combined.')
|
||||
|
||||
receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.receivable_account)
|
||||
self.assertAlmostEqual(receivable_line.balance, -691.06, msg='That is not the correct receivable line balance.')
|
||||
|
||||
other_receivable_line = session_move.line_ids.filtered(lambda line: line.account_id == self.other_receivable_account)
|
||||
self.assertAlmostEqual(other_receivable_line.balance, -265.75, msg='That is not the correct other receivable line balance.')
|
||||
|
||||
self.assertTrue(receivable_line_cash.full_reconcile_id)
|
||||
self.assertTrue(receivable_line.full_reconcile_id)
|
||||
self.assertTrue(other_receivable_line.full_reconcile_id)
|
||||
Reference in New Issue
Block a user