def test_tax_rule_children(self):
        "Test tax rule with children subdivision"
        country = self._create_countries()[0]
        parent_subdivision = [s for s in country.subdivisions
                              if not s.parent][0]
        subdivision = [
            s for s in country.subdivisions if s.parent == parent_subdivision
        ][0]
        company = create_company()
        with set_company(company):
            create_chart(company, tax=True)
            tax, target_tax = self._get_taxes()[:2]
            tax_rule = self._create_rule([{
                'to_country':
                country.id,
                'to_subdivision':
                parent_subdivision.id,
                'origin_tax':
                tax.id,
                'tax':
                target_tax.id,
            }])
            pattern = {
                'to_country': country.id,
                'to_subdivision': subdivision.id,
            }

            self.assertListEqual(tax_rule.apply(tax, pattern), [target_tax.id])
    def test_payment_sepa_bank_account_number(self):
        'Test Payment.sepa_bank_account_number'
        pool = Pool()
        Payment = pool.get('account.payment')
        Mandate = pool.get('account.payment.sepa.mandate')
        AccountNumber = pool.get('bank.account.number')
        Party = pool.get('party.party')
        BankAccount = pool.get('bank.account')

        company = create_company()
        with set_company(company):
            create_chart(company)
            account_number = AccountNumber()
            mandate = Mandate(account_number=account_number)
            payment = Payment(kind='receivable', sepa_mandate=mandate)

            self.assertEqual(id(payment.sepa_bank_account_number),
                id(account_number))

            other_account_number = AccountNumber(type='other')
            iban_account_number = AccountNumber(type='iban')
            bank_account = BankAccount(
                numbers=[other_account_number, iban_account_number])
            party = Party(
                bank_accounts=[bank_account])
            payment = Payment(kind='payable', party=party)

            self.assertEqual(id(payment.sepa_bank_account_number),
                id(iban_account_number))
    def test_tax_rule(self):
        "Test tax rule"
        country1, country2 = self._create_countries()[:2]
        subdivision1 = country1.subdivisions[0]
        subdivision2 = country2.subdivisions[0]
        company = create_company()
        with set_company(company):
            create_chart(company, tax=True)
            tax, target_tax = self._get_taxes()[:2]
            tax_rule = self._create_rule([{
                'from_country': country1.id,
                'from_subdivision': subdivision1.id,
                'to_country': country2.id,
                'to_subdivision': subdivision2.id,
                'origin_tax': tax.id,
                'tax': target_tax.id,
            }])
            pattern = {
                'from_country': country1.id,
                'from_subdivision': subdivision1.id,
                'to_country': country2.id,
                'to_subdivision': subdivision2.id,
            }

            self.assertListEqual(tax_rule.apply(tax, pattern), [target_tax.id])
Beispiel #4
0
    def test_payment_sepa_bank_account_number(self):
        'Test Payment.sepa_bank_account_number'
        pool = Pool()
        Payment = pool.get('account.payment')
        Mandate = pool.get('account.payment.sepa.mandate')
        AccountNumber = pool.get('bank.account.number')
        Party = pool.get('party.party')
        BankAccount = pool.get('bank.account')

        company = create_company()
        with set_company(company):
            create_chart(company)
            account_number = AccountNumber()
            mandate = Mandate(account_number=account_number)
            payment = Payment(kind='receivable', sepa_mandate=mandate)

            self.assertEqual(id(payment.sepa_bank_account_number),
                             id(account_number))

            other_account_number = AccountNumber(type='other')
            iban_account_number = AccountNumber(type='iban')
            bank_account = BankAccount(
                numbers=[other_account_number, iban_account_number])
            party = Party(bank_accounts=[bank_account])
            payment = Payment(kind='payable', party=party)

            self.assertEqual(id(payment.sepa_bank_account_number),
                             id(iban_account_number))
Beispiel #5
0
    def create_product_supplier(self, lead_time):
        '''
        Create a Product with a Product Supplier

        :param lead_time: timedelta needed to supply
        :return: the id of the Product Supplier
        '''
        pool = Pool()
        Uom = pool.get('product.uom')
        UomCategory = pool.get('product.uom.category')
        Category = pool.get('product.category')
        Template = pool.get('product.template')
        Product = pool.get('product.product')
        Party = pool.get('party.party')
        Account = pool.get('account.account')
        ProductSupplier = pool.get('purchase.product_supplier')

        uom_category, = UomCategory.create([{'name': 'Test'}])
        uom, = Uom.create([{
                    'name': 'Test',
                    'symbol': 'T',
                    'category': uom_category.id,
                    'rate': 1.0,
                    'factor': 1.0,
                    }])
        category, = Category.create([{'name': 'ProdCategoryTest'}])
        template, = Template.create([{
                    'name': 'ProductTest',
                    'default_uom': uom.id,
                    'category': category.id,
                    'account_category': True,
                    'list_price': Decimal(0),
                    'cost_price': Decimal(0),
                    }])
        product, = Product.create([{
                    'template': template.id,
                    }])
        company = create_company()
        with set_company(company):
            create_chart(company)
            receivable, = Account.search([
                ('kind', '=', 'receivable'),
                ('company', '=', company.id),
                ])
            payable, = Account.search([
                ('kind', '=', 'payable'),
                ('company', '=', company.id),
                ])
            supplier, = Party.create([{
                        'name': 'supplier',
                        'account_receivable': receivable.id,
                        'account_payable': payable.id,
                        }])
            product_supplier, = ProductSupplier.create([{
                        'product': template.id,
                        'company': company.id,
                        'party': supplier.id,
                        'lead_time': lead_time,
                        }])
            return product_supplier
    def test_move_lines(self):
        'Test move lines'
        pool = Pool()
        Account = pool.get('account.account')
        FiscalYear = pool.get('account.fiscalyear')
        Journal = pool.get('account.journal')
        Move = pool.get('account.move')
        MoveLine = pool.get('account.move.line')
        PaymentType = pool.get('account.payment.type')

        company = create_company()
        with set_company(company):
            create_chart(company)
            fiscalyear = get_fiscalyear(company)
            set_invoice_sequences(fiscalyear)
            fiscalyear.save()
            FiscalYear.create_period([fiscalyear])
            period = fiscalyear.periods[0]

            journal_revenue, = Journal.search([
                    ('code', '=', 'REV'),
                    ])
            revenue, = Account.search([
                    ('type.revenue', '=', True),
                    ])
            receivable, = Account.search([
                    ('type.receivable', '=', True),
                    ])
            payable, = Account.search([
                    ('type.payable', '=', True),
                    ])
            payment_payable, = PaymentType.create([{
                    'name': 'Payment Payable',
                    'kind': 'payable',
                    'company': company.id,
                    }])
            payment_receivable, = PaymentType.create([{
                    'name': 'Payment Receivable',
                    'kind': 'receivable',
                    'company': company.id,
                    }])
            move, = Move.create([{
                    'period': period.id,
                    'journal': journal_revenue.id,
                    'date': period.start_date,
                    }])
            MoveLine.create([{
                    'move': move.id,
                    'account': revenue.id,
                    'debit': Decimal(30),
                    }])
            self.assertRaises(Exception, MoveLine.create, [{
                    'move': move.id,
                    'account': revenue.id,
                    'debit': Decimal(30),
                    'payment_type': payment_receivable,
                    }])
Beispiel #7
0
    def test_account_chart_many_companies(self):
        "Test creation of chart of accounts for many companies"
        company1 = create_company()
        with set_company(company1):
            create_chart(company1, tax=True)

        company2 = create_company()
        with set_company(company2):
            create_chart(company2, tax=True)
    def create_product_supplier(self, lead_time):
        '''
        Create a Product with a Product Supplier

        :param lead_time: timedelta needed to supply
        :return: the id of the Product Supplier
        '''
        pool = Pool()
        Uom = pool.get('product.uom')
        UomCategory = pool.get('product.uom.category')
        Template = pool.get('product.template')
        Product = pool.get('product.product')
        Party = pool.get('party.party')
        Account = pool.get('account.account')
        ProductSupplier = pool.get('purchase.product_supplier')

        uom_category, = UomCategory.create([{'name': 'Test'}])
        uom, = Uom.create([{
            'name': 'Test',
            'symbol': 'T',
            'category': uom_category.id,
            'rate': 1.0,
            'factor': 1.0,
        }])
        template, = Template.create([{
            'name': 'ProductTest',
            'default_uom': uom.id,
            'list_price': Decimal(0),
            'cost_price': Decimal(0),
        }])
        product, = Product.create([{
            'template': template.id,
        }])
        company = create_company()
        with set_company(company):
            create_chart(company)
            receivable, = Account.search([
                ('kind', '=', 'receivable'),
                ('company', '=', company.id),
            ])
            payable, = Account.search([
                ('kind', '=', 'payable'),
                ('company', '=', company.id),
            ])
            supplier, = Party.create([{
                'name': 'supplier',
                'account_receivable': receivable.id,
                'account_payable': payable.id,
            }])
            product_supplier, = ProductSupplier.create([{
                'product': template.id,
                'company': company.id,
                'party': supplier.id,
                'lead_time': lead_time,
            }])
            return product_supplier
Beispiel #9
0
    def test_create_sale(self):
        pool = Pool()
        User = pool.get('res.user')
        Sequence = pool.get('ir.sequence')
        Currency = pool.get('currency.currency')
        Location = pool.get('stock.location')
        PaymentTerm = pool.get('account.invoice.payment_term')
        PriceList = pool.get('product.price_list')
        Shop = pool.get('sale.shop')
        Sale = pool.get('sale.sale')

        company = create_company()
        with set_company(company):
            create_chart(company)
            # update sale configuration
            sale_configuration()

            payment_term, = PaymentTerm.search([], limit=1)
            product_price_list, = PriceList.search([], limit=1)
            warehouse, = Location.search([('type', '=', 'warehouse')], limit=1)
            currency, = Currency.search([], limit=1)
            sequence, = Sequence.search([('code', '=', 'sale.sale')], limit=1)

            shop = Shop()
            shop.name = 'Shop test'
            shop.warehouse = warehouse
            shop.currency = currency
            shop.sale_sequence = sequence
            shop.price_list = product_price_list
            shop.payment_term = payment_term
            shop.sale_invoice_method = 'shipment'
            shop.sale_shipment_method = 'order'
            shop.esale_ext_reference = True
            shop.save()

            # set user shop
            user = User(Transaction().user)
            user.shops = [shop]
            user.shop = shop
            user.save()

            Sale.create_external_order(
                shop,
                sale_values=sale_values(number='S0001'),
                lines_values=[lines_values(code='P0001')],
                party_values=party_values(),
                invoice_values=invoice_values(),
                shipment_values=shipment_values())

            sale, = Sale.search([('number', '=', 'S0001')], limit=1)
            self.assertEqual(sale.number, 'S0001')
            self.assertEqual(sale.comment, u'Example Sale Order')
            self.assertEqual(sale.total_amount, Decimal('10.00'))
    def test_account_chart(self):
        'Test creation and update of minimal chart of accounts'
        pool = Pool()
        Account = pool.get('account.account')
        UpdateChart = pool.get('account.update_chart', type='wizard')

        company = create_company()
        with set_company(company):
            create_chart(company, tax=True)
            root, = Account.search([('parent', '=', None)])

            session_id, _, _ = UpdateChart.create()
            update_chart = UpdateChart(session_id)
            update_chart.start.account = root
            update_chart.transition_update()
Beispiel #11
0
    def test_sale_price(self):
        "Test sale price"
        pool = Pool()
        Account = pool.get('account.account')
        Template = pool.get('product.template')
        Product = pool.get('product.product')
        Uom = pool.get('product.uom')

        company = create_company()
        with set_company(company):
            create_chart(company)

            receivable, = Account.search([
                    ('type.receivable', '=', True),
                    ('company', '=', company.id),
                    ])
            payable, = Account.search([
                    ('type.payable', '=', True),
                    ('company', '=', company.id),
                    ])

            kg, = Uom.search([('name', '=', 'Kilogram')])
            g, = Uom.search([('name', '=', 'Gram')])
            pound, = Uom.search([('name', '=', 'Pound')])

            template, = Template.create([{
                        'name': 'Product',
                        'default_uom': g.id,
                        'sale_uom': kg.id,
                        'list_price': Decimal(5),
                        'products': [('create', [{}])],
                        }])
            product, = template.products

            prices = Product.get_sale_price([product], quantity=100)
            self.assertEqual(prices, {product.id: Decimal(5000)})
            prices = Product.get_sale_price([product], quantity=1500)
            self.assertEqual(prices, {product.id: Decimal(5000)})

            with Transaction().set_context(uom=pound.id):
                prices = Product.get_sale_price([product], quantity=0.5)
                self.assertEqual(prices, {product.id: Decimal('2267.96185')})
                prices = Product.get_sale_price([product], quantity=1.5)
                self.assertEqual(prices, {product.id: Decimal('2267.96185')})
    def test_tax_rule_no_subdivision_pattern(self):
        "Test tax rule without subdivision in pattern"
        country = self._create_countries()[0]
        subdivision = country.subdivisions[0]
        company = create_company()
        with set_company(company):
            create_chart(company, tax=True)
            tax, target_tax = self._get_taxes()[:2]
            tax_rule = self._create_rule([{
                'to_country': country.id,
                'to_subdivision': subdivision.id,
                'origin_tax': tax.id,
                'tax': target_tax.id,
            }])
            pattern = {
                'to_country': country.id,
            }

            self.assertListEqual(tax_rule.apply(tax, pattern), [tax.id])
    def test_account_used(self):
        'Test account used'
        pool = Pool()
        ProductTemplate = pool.get('product.template')
        ProductCategory = pool.get('product.category')
        Uom = pool.get('product.uom')
        Account = pool.get('account.account')

        company = create_company()
        with set_company(company):
            create_chart(company)

            unit, = Uom.search([
                ('name', '=', 'Unit'),
            ])
            account_expense, = Account.search([
                ('kind', '=', 'expense'),
            ])

            # raise when empty
            template = ProductTemplate(
                name='test account used',
                list_price=Decimal(10),
                cost_price=Decimal(3),
                default_uom=unit.id,
            )
            template.save()

            self.assertIsNone(template.account_expense)

            with self.assertRaises(UserError):
                template.account_expense_used

            # with account
            template = ProductTemplate(
                name='test account used',
                list_price=Decimal(10),
                cost_price=Decimal(3),
                default_uom=unit.id,
                account_expense=account_expense.id,
            )
            template.save()

            self.assertEqual(template.account_expense, account_expense)
            self.assertEqual(template.account_expense_used, account_expense)

            # with account on category
            category = ProductCategory(name='test account used',
                                       account_expense=account_expense,
                                       accounting=True)
            category.save()
            template.account_expense = None
            template.accounts_category = True
            template.account_category = category
            template.save()

            self.assertIsNone(template.account_expense)
            self.assertEqual(template.account_expense_used, account_expense)

            # with account on grant category
            parent_category = ProductCategory(name='parent account used',
                                              account_expense=account_expense,
                                              accounting=True)
            parent_category.save()
            category.account_expense = None
            category.account_parent = True
            category.parent = parent_category
            category.save()

            self.assertIsNone(category.account_expense)
            self.assertEqual(template.account_expense_used, account_expense)
            self.assertEqual(category.account_expense_used, account_expense)

            # raise only at direct usage
            templates = ProductTemplate.create([{
                'name':
                'test with account',
                'list_price':
                Decimal(10),
                'cost_price':
                Decimal(3),
                'default_uom':
                unit.id,
                'account_expense':
                account_expense.id,
            }, {
                'name': 'test without account',
                'list_price': Decimal(10),
                'cost_price': Decimal(3),
                'default_uom': unit.id,
                'account_expense': None,
            }])

            self.assertEqual(templates[0].account_expense_used.id,
                             account_expense.id)

            with self.assertRaises(UserError):
                templates[1].account_expense_used
Beispiel #14
0
    def test_purchase_price(self):
        'Test purchase price'
        pool = Pool()
        Account = pool.get('account.account')
        Template = pool.get('product.template')
        Product = pool.get('product.product')
        Uom = pool.get('product.uom')
        ProductSupplier = pool.get('purchase.product_supplier')
        Party = pool.get('party.party')

        company = create_company()
        with set_company(company):
            create_chart(company)

            receivable, = Account.search([
                    ('kind', '=', 'receivable'),
                    ('company', '=', company.id),
                    ])
            payable, = Account.search([
                    ('kind', '=', 'payable'),
                    ('company', '=', company.id),
                    ])

            kg, = Uom.search([('name', '=', 'Kilogram')])
            g, = Uom.search([('name', '=', 'Gram')])

            template, = Template.create([{
                        'name': 'Product',
                        'default_uom': g.id,
                        'purchase_uom': kg.id,
                        'list_price': Decimal(5),
                        'cost_price': Decimal(2),
                        'products': [('create', [{}])],
                        }])
            product, = template.products

            supplier, = Party.create([{
                        'name': 'Supplier',
                        'account_receivable': receivable.id,
                        'account_payable': payable.id,
                        }])
            product_supplier, = ProductSupplier.create([{
                        'product': template.id,
                        'party': supplier.id,
                        'prices': [('create', [{
                                        'sequence': 1,
                                        'quantity': 1,
                                        'unit_price': Decimal(3000),
                                        }, {
                                        'sequence': 2,
                                        'quantity': 2,
                                        'unit_price': Decimal(2500),
                                        }])],
                        }])

            prices = Product.get_purchase_price([product], quantity=100)
            self.assertEqual(prices, {product.id: Decimal(2)})
            prices = Product.get_purchase_price([product], quantity=1500)
            self.assertEqual(prices, {product.id: Decimal(2)})

            with Transaction().set_context(uom=kg.id):
                prices = Product.get_purchase_price([product], quantity=0.5)
                self.assertEqual(prices, {product.id: Decimal(2000)})
                prices = Product.get_purchase_price([product], quantity=1.5)
                self.assertEqual(prices, {product.id: Decimal(2000)})

            with Transaction().set_context(supplier=supplier.id):
                prices = Product.get_purchase_price([product], quantity=100)
                self.assertEqual(prices, {product.id: Decimal(2)})
                prices = Product.get_purchase_price([product], quantity=1500)
                self.assertEqual(prices, {product.id: Decimal(3)})
                prices = Product.get_purchase_price([product], quantity=3000)
                self.assertEqual(prices, {product.id: Decimal('2.5')})

            with Transaction().set_context(uom=kg.id, supplier=supplier.id):
                prices = Product.get_purchase_price([product], quantity=0.5)
                self.assertEqual(prices, {product.id: Decimal(2000)})
                prices = Product.get_purchase_price([product], quantity=1.5)
                self.assertEqual(prices, {product.id: Decimal(3000)})
                prices = Product.get_purchase_price([product], quantity=3)
                self.assertEqual(prices, {product.id: Decimal(2500)})
Beispiel #15
0
 def test_create_chart(self):
     company = create_company()
     with set_company(company):
         create_chart(company, chart=self.module + '.root_' + self.language)
Beispiel #16
0
    def test_account_debit_credit(self):
        'Test account debit/credit'
        pool = Pool()
        Party = pool.get('party.party')
        AnalyticAccount = pool.get('analytic_account.account')
        Journal = pool.get('account.journal')
        Account = pool.get('account.account')
        Move = pool.get('account.move')
        transaction = Transaction()

        party = Party(name='Party')
        party.save()
        company = create_company()
        with set_company(company):
            root, = AnalyticAccount.create([{
                        'type': 'root',
                        'name': 'Root',
                        }])
            analytic_account, = AnalyticAccount.create([{
                        'type': 'normal',
                        'name': 'Analytic Account',
                        'parent': root.id,
                        'root': root.id,
                        }])
            create_chart(company)
            fiscalyear = get_fiscalyear(company)
            fiscalyear.save()
            fiscalyear.create_period([fiscalyear])
            period = fiscalyear.periods[0]
            journal_revenue, = Journal.search([
                    ('code', '=', 'REV'),
                    ])
            journal_expense, = Journal.search([
                    ('code', '=', 'EXP'),
                    ])
            revenue, = Account.search([
                    ('kind', '=', 'revenue'),
                    ])
            receivable, = Account.search([
                    ('kind', '=', 'receivable'),
                    ])
            expense, = Account.search([
                    ('kind', '=', 'expense'),
                    ])
            payable, = Account.search([
                    ('kind', '=', 'payable'),
                    ])

            first_account_line = {
                'account': revenue.id,
                'credit': Decimal(100),
                'analytic_lines': [
                    ('create', [{
                                'account': analytic_account.id,
                                'name': 'Analytic Line',
                                'credit': Decimal(100),
                                'debit': Decimal(0),
                                'journal': journal_revenue.id,
                                'date': period.start_date,
                                }])
                    ]}
            second_account_line = {
                'account': expense.id,
                'debit': Decimal(30),
                'analytic_lines': [
                    ('create', [{
                                'account': analytic_account.id,
                                'name': 'Analytic Line',
                                'debit': Decimal(30),
                                'credit': Decimal(0),
                                'journal': journal_expense.id,
                                'date': period.start_date,
                                }])
                    ]}
            # Create some moves
            vlist = [{
                    'period': period.id,
                    'journal': journal_revenue.id,
                    'date': period.start_date,
                    'lines': [
                        ('create', [first_account_line, {
                                    'account': receivable.id,
                                    'debit': Decimal(100),
                                    'party': party.id,
                                    }]),
                        ],
                    }, {
                    'period': period.id,
                    'journal': journal_expense.id,
                    'date': period.start_date,
                    'lines': [
                        ('create', [second_account_line, {
                                    'account': payable.id,
                                    'credit': Decimal(30),
                                    'party': party.id,
                                    }]),
                        ],
                    },
                ]
            Move.create(vlist)

            self.assertEqual((analytic_account.debit, analytic_account.credit),
                (Decimal(30), Decimal(100)))
            self.assertEqual(analytic_account.balance, Decimal(70))

            with transaction.set_context(start_date=period.end_date):
                analytic_account = AnalyticAccount(analytic_account.id)
                self.assertEqual((analytic_account.debit,
                        analytic_account.credit),
                    (Decimal(0), Decimal(0)))
                self.assertEqual(analytic_account.balance, Decimal(0))

            with transaction.set_context(end_date=period.end_date):
                analytic_account = AnalyticAccount(analytic_account.id)
                self.assertEqual((analytic_account.debit,
                        analytic_account.credit),
                    (Decimal(30), Decimal(100)))
                self.assertEqual(analytic_account.balance, Decimal(70))
    def test_check_credit_limit(self):
        'Test check_credit_limit'
        pool = Pool()
        Account = pool.get('account.account')
        Move = pool.get('account.move')
        Journal = pool.get('account.journal')
        Party = pool.get('party.party')
        Sale = pool.get('sale.sale')
        PaymentTerm = pool.get('account.invoice.payment_term')
        Property = pool.get('ir.property')
        ModelField = pool.get('ir.model.field')
        FiscalYear = pool.get('account.fiscalyear')

        company = create_company()
        with set_company(company):
            create_chart(company)
            fiscalyear = set_invoice_sequences(get_fiscalyear(company))
            fiscalyear.save()
            FiscalYear.create_period([fiscalyear])
            period = fiscalyear.periods[0]

            receivable, = Account.search([
                ('kind', '=', 'receivable'),
            ])
            revenue, = Account.search([
                ('kind', '=', 'revenue'),
            ])
            journal, = Journal.search([], limit=1)
            party, = Party.create([{
                'name': 'Party',
                'addresses': [
                    ('create', [{}]),
                ],
                'credit_limit_amount': Decimal('100'),
            }])
            Move.create([{
                'journal':
                journal.id,
                'period':
                period.id,
                'date':
                period.start_date,
                'lines': [
                    ('create', [{
                        'debit': Decimal('100'),
                        'account': receivable.id,
                        'party': party.id,
                    }, {
                        'credit': Decimal('100'),
                        'account': revenue.id,
                    }]),
                ],
            }])
            payment_term, = PaymentTerm.create([{
                'name':
                'Test',
                'lines': [('create', [{
                    'type': 'remainder',
                }])],
            }])
            field, = ModelField.search([
                ('model.model', '=', 'product.template'),
                ('name', '=', 'account_revenue'),
            ],
                                       limit=1)
            Property.create([{
                'field': field.id,
                'value': str(revenue),
                'company': company.id,
            }])
            sale, = Sale.create([{
                'party':
                party.id,
                'company':
                company.id,
                'payment_term':
                payment_term.id,
                'currency':
                company.currency.id,
                'invoice_address':
                party.addresses[0].id,
                'shipment_address':
                party.addresses[0].id,
                'lines': [
                    ('create', [{
                        'description': 'Test',
                        'quantity': 1,
                        'unit_price': Decimal('50'),
                    }]),
                ],
            }])
            self.assertEqual(party.credit_amount, Decimal('100'))
            Sale.quote([sale])
            Sale.confirm([sale])
            self.assertEqual(party.credit_amount, Decimal('100'))
            # Test limit reaches
            self.assertRaises(UserWarning, Sale.process, [sale])
            # Increase limit
            party.credit_limit_amount = Decimal('200')
            party.save()
            # process should work
            Sale.process([sale])
            self.assertEqual(sale.state, 'processing')
            self.assertEqual(party.credit_amount, Decimal('150'))

            # Re-process
            Sale.process([sale])
            # Decrease limit
            party.credit_limit_amount = Decimal('100')
            party.save()
            # process should still work as sale is already processing
            Sale.process([sale])
    def test_check_credit_limit(self):
        'Test check_credit_limit'
        pool = Pool()
        Account = pool.get('account.account')
        Move = pool.get('account.move')
        Journal = pool.get('account.journal')
        Party = pool.get('party.party')
        Sale = pool.get('sale.sale')
        PaymentTerm = pool.get('account.invoice.payment_term')
        Property = pool.get('ir.property')
        ModelField = pool.get('ir.model.field')
        FiscalYear = pool.get('account.fiscalyear')

        company = create_company()
        with set_company(company):
            create_chart(company)
            fiscalyear = set_invoice_sequences(get_fiscalyear(company))
            fiscalyear.save()
            FiscalYear.create_period([fiscalyear])
            period = fiscalyear.periods[0]

            receivable, = Account.search([
                    ('kind', '=', 'receivable'),
                    ])
            revenue, = Account.search([
                    ('kind', '=', 'revenue'),
                    ])
            journal, = Journal.search([], limit=1)
            party, = Party.create([{
                        'name': 'Party',
                        'addresses': [
                            ('create', [{}]),
                            ],
                        'credit_limit_amount': Decimal('100'),
                        }])
            Move.create([{
                        'journal': journal.id,
                        'period': period.id,
                        'date': period.start_date,
                        'lines': [
                            ('create', [{
                                        'debit': Decimal('100'),
                                        'account': receivable.id,
                                        'party': party.id,
                                        }, {
                                        'credit': Decimal('100'),
                                        'account': revenue.id,
                                        }]),
                            ],
                        }])
            payment_term, = PaymentTerm.create([{
                        'name': 'Test',
                        'lines': [
                            ('create', [{
                                        'type': 'remainder',
                                        }])
                            ],
                        }])
            field, = ModelField.search([
                    ('model.model', '=', 'product.template'),
                    ('name', '=', 'account_revenue'),
                    ], limit=1)
            Property.create([{
                    'field': field.id,
                    'value': str(revenue),
                    'company': company.id,
                    }])
            sale, = Sale.create([{
                        'party': party.id,
                        'company': company.id,
                        'payment_term': payment_term.id,
                        'currency': company.currency.id,
                        'invoice_address': party.addresses[0].id,
                        'shipment_address': party.addresses[0].id,
                        'lines': [
                            ('create', [{
                                        'description': 'Test',
                                        'quantity': 1,
                                        'unit_price': Decimal('50'),
                                        }]),
                            ],
                        }])
            self.assertEqual(party.credit_amount, Decimal('100'))
            Sale.quote([sale])
            Sale.confirm([sale])
            self.assertEqual(party.credit_amount, Decimal('100'))
            # Test limit reaches
            self.assertRaises(UserWarning, Sale.process, [sale])
            # Increase limit
            party.credit_limit_amount = Decimal('200')
            party.save()
            # process should work
            Sale.process([sale])
            self.assertEqual(sale.state, 'processing')
            self.assertEqual(party.credit_amount, Decimal('150'))

            # Re-process
            Sale.process([sale])
            # Decrease limit
            party.credit_limit_amount = Decimal('100')
            party.save()
            # process should still work as sale is already processing
            Sale.process([sale])
    def test_advance(self):
        pool = Pool()
        Account = pool.get('account.account')
        Config = pool.get('cash_bank.configuration')
        Receipt = pool.get('cash_bank.receipt')
        Advance = pool.get('cash_bank.advance')
        AdvanceLineApplied = pool.get('cash_bank.advance.line_applied')

        party = self._create_party('Party test', None)

        transaction = Transaction()

        company = create_company()
        with set_company(company):
            create_chart(company)
            create_fiscalyear(company)

            account_cash, = Account.search([
                ('name', '=', 'Main Cash'),
            ])
            account_revenue, = Account.search([
                ('name', '=', 'Main Revenue'),
            ])
            account_expense, = Account.search([
                ('name', '=', 'Main Expense'),
            ])
            account_receivable, = Account.search([
                ('name', '=', 'Main Receivable'),
            ])
            account_payable, = Account.search([
                ('name', '=', 'Main Payable'),
            ])

            config = Config(
                default_collected_in_advanced_account=account_payable,
                default_paid_in_advanced_account=account_receivable)
            config.save()

            journal = create_journal(company, 'journal_cash')

            sequence = create_sequence('Cash/Bank Sequence',
                                       'cash_bank.receipt', company)
            sequence_convertion = create_sequence('Cash/Bank Convertion',
                                                  'cash_bank.convertion',
                                                  company)

            config.convertion_seq = sequence_convertion
            config.save()

            cashier = create_cash_bank(
                company,
                'Main Cash',
                'cash',
                journal,
                account_cash,
                sequence,
            )

            date = datetime.date.today()

            # Test Collected in advance from Customer
            self._basic_advance(company, cashier, 'in', date, party,
                                account_payable, account_expense)

            # Test Paid in advance to Supplier
            self._basic_advance(company, cashier, 'out', date, party,
                                account_receivable, account_expense)
Beispiel #20
0
    def test_cash_bank(self):
        pool = Pool()
        Account = pool.get('account.account')
        Config = pool.get('cash_bank.configuration')
        Receipt = pool.get('cash_bank.receipt')
        ReceiptLine = pool.get('cash_bank.receipt.line')
        DocumentType = pool.get('cash_bank.document.type')
        Document = pool.get('cash_bank.document')
        Docs = pool.get('cash_bank.document-cash_bank.receipt')
        Transfer = pool.get('cash_bank.transfer')
        Convertion = pool.get('cash_bank.convertion')
        CashBank = pool.get('cash_bank.cash_bank')
        ReceiptType = pool.get('cash_bank.receipt_type')

        party = self._create_party('Party test', None)

        transaction = Transaction()

        company = create_company()
        with set_company(company):
            create_chart(company)
            create_fiscalyear(company)

            account_transfer, = Account.search([
                    ('name', '=', 'Main Expense'),
                    ])
            account_cash, = Account.search([
                    ('name', '=', 'Main Cash'),
                    ])
            account_revenue, = Account.search([
                    ('name', '=', 'Main Revenue'),
                    ])
            account_expense, = Account.search([
                    ('name', '=', 'Main Expense'),
                    ])

            journal = create_journal(company, 'journal_cash')

            config = Config(
                account_transfer=account_transfer)
            config.save()

            cheque_type = DocumentType(name='Cheque')
            cheque_type.save()

            sequence = create_sequence(
                'Cash/Bank Sequence',
                'cash_bank.receipt',
                company)
            sequence_convertion = create_sequence(
                'Cash/Bank Convertion',
                'cash_bank.convertion',
                company)

            config.convertion_seq = sequence_convertion
            config.save()

            cash = create_cash_bank(
                company, 'Main Cashier', 'cash',
                journal, account_cash, sequence
                )
            self.assertEqual(len(cash.receipt_types), 2)

            _, bank_account = create_bank_account(
                party_bank=self._create_party('Party Bank', None),
                party_owner=company.party)

            with self.assertRaises(SQLConstraintError):
                # Must be a diferent account
                bank = create_cash_bank(
                    company, 'Main Bank', 'bank',
                    journal, account_cash, sequence,
                    bank_account
                    )

            with self.assertRaises(RequiredValidationError):
                # Bank Account is required for type bank
                bank = create_cash_bank(
                    company, 'Main Bank', 'bank',
                    journal, account_revenue, sequence
                    )
            ReceiptType.delete(ReceiptType.search(
                [('cash_bank.type', '=', 'bank')]))
            CashBank.delete(CashBank.search(
                [('type', '=', 'bank')]))

            bank = create_cash_bank(
                company, 'Main Bank', 'bank',
                journal, account_revenue, sequence,
                bank_account
                )
            self.assertEqual(len(bank.receipt_types), 2)

            date = datetime.date.today()

            # Receipt Cash IN
            receipt = create_receipt(
                company, cash, 'in', date)

            receipt.cash = Decimal('100.0')
            receipt.save()

            self.assertEqual(receipt.state, 'draft')
            self.assertEqual(receipt.diff, Decimal('-100.0'))

            line = ReceiptLine(
                receipt=receipt,
                amount=Decimal('100.0'),
                account=account_revenue
                )

            receipt.lines = [line]
            receipt.save()

            self.assertEqual(len(receipt.lines), 1)
            self.assertEqual(receipt.diff, Decimal('0.0'))
            self.assertEqual(receipt.state, 'draft')
            self.assertEqual(receipt.move, None)

            Receipt.confirm([receipt])
            self.assertEqual(receipt.state, 'confirmed')
            self.assertEqual(receipt.move.state, 'draft')

            Receipt.cancel([receipt])
            self.assertEqual(receipt.state, 'cancel')
            self.assertEqual(receipt.move, None)

            Receipt.draft([receipt])
            self.assertEqual(receipt.state, 'draft')
            self.assertEqual(receipt.move, None)

            Receipt.confirm([receipt])
            self.assertEqual(receipt.state, 'confirmed')
            self.assertEqual(receipt.move.state, 'draft')

            Receipt.post([receipt])
            self.assertEqual(receipt.state, 'posted')
            self.assertEqual(receipt.move.state, 'posted')

            # Nothing change because 'posted' to 'cancel'
            # not in cls._transitions
            Receipt.cancel([receipt])
            self.assertEqual(receipt.state, 'posted')
            self.assertEqual(receipt.move.state, 'posted')

            # Receipt Cash OUT
            receipt = create_receipt(
                company, cash, 'out', date, party)

            receipt.cash = Decimal('100.0')
            receipt.save()

            line = ReceiptLine(
                receipt=receipt,
                amount=Decimal('100.0'),
                account=account_expense
                )

            receipt.lines = [line]
            receipt.save()

            Receipt.confirm([receipt])
            Receipt.post([receipt])

            # 'out' receipts can not create documents
            receipt = create_receipt(
                company, cash, 'out', date)
            receipt.cash = Decimal('10.0')
            receipt.save()
            with self.assertRaises(UserError):
                docs = [
                    self._get_document(
                        cheque_type, Decimal('20.0'), date, 'a'),
                    self._get_document(
                        cheque_type, Decimal('30.0'), date, 'b'),
                    self._get_document(
                        cheque_type, Decimal('40.0'), date, 'c'),
                    ]
                receipt.documents = docs
                receipt.save()
            Receipt.delete([receipt])
            Document.delete(Document.search([]))

            # Receipt IN with cash and documents

            receipt = create_receipt(
                company, cash, 'in', date)
            receipt.cash = Decimal('10.0')

            docs = [
                self._get_document(
                    cheque_type, Decimal('20.0'), date, 'abc'),
                self._get_document(
                    cheque_type, Decimal('30.0'), date, 'def'),
                self._get_document(
                    cheque_type, Decimal('40.0'), date, 'ghi'),
                ]
            receipt.documents = docs
            receipt.save()

            self.assertEqual(len(receipt.documents), 3)
            self.assertEqual(receipt.total_documents, Decimal('90.0'))
            self.assertEqual(receipt.total, Decimal('100.0'))
            self.assertEqual(receipt.diff, Decimal('-100.0'))

            self._verify_document('abc', receipt.id)
            self._verify_document('def', receipt.id)
            self._verify_document('ghi', receipt.id)

            line = ReceiptLine(
                receipt=receipt,
                amount=Decimal('100.0'),
                account=account_revenue
                )
            receipt.lines = [line]
            receipt.save()

            Receipt.confirm([receipt])

            with self.assertRaises(UserError):
                # Should be 'draft' state
                Receipt.delete([receipt])

            Receipt.cancel([receipt])
            Receipt.draft([receipt])
            Receipt.delete([receipt])

            docs = Docs.search([])  # cash_bank.document-cash_bank.receipt
            self.assertEqual(len(docs), 0)

            docs = Document.search([])  # cash_bank.document
            self.assertEqual(len(docs), 3)
            self._verify_document('abc', None)
            self._verify_document('def', None)
            self._verify_document('ghi', None)

            ########################
            # Documents domain tests
            ########################

            receipt_1 = create_receipt(
                company, cash, 'in', date)
            receipt_1.cash = Decimal('10.0')
            receipt_1.lines = [
                ReceiptLine(
                    amount=Decimal('100.0'),
                    account=account_expense
                )]
            receipt_1.documents = Document.search([])
            receipt_1.save()
            self._verify_document('abc', receipt_1.id)
            self._verify_document('def', receipt_1.id)
            self._verify_document('ghi', receipt_1.id)

            # if documents are detached then returns to a previous receipt
            receipt_1.documents = [Document.search([])[0]]
            receipt_1.save()
            self._verify_document('abc', receipt_1.id)
            self._verify_document('def', None)
            self._verify_document('ghi', None)
            Receipt.delete([receipt_1])

            # Ensure that if docs belongs to a receipt 'in'
            # no other receipt 'in' can add them
            receipt_1 = create_receipt(
                company, cash, 'in', date)
            receipt_1.cash = Decimal('10.0')
            receipt_1.lines = [
                ReceiptLine(
                    amount=Decimal('100.0'),
                    account=account_expense
                )]
            receipt_1.documents = Document.search([])
            receipt_1.save()
            self._validate_domain_in(Receipt, Document, receipt_1)

            # Same if receipt_1 is confirmed
            Receipt.confirm([receipt_1])
            self._validate_domain_in(Receipt, Document, receipt_1)

            # Same if receipt_1 is canceled
            Receipt.cancel([receipt_1])
            self.assertEqual(receipt_1.state, 'cancel')
            self.assertEqual(receipt_1.move, None)
            self._validate_domain_in(Receipt, Document, receipt_1)

            # Same if receipt_1 is draft
            Receipt.draft([receipt_1])
            self._validate_domain_in(Receipt, Document, receipt_1)

            # Same if receipt_1 is confirmed
            Receipt.confirm([receipt_1])
            self._validate_domain_in(Receipt, Document, receipt_1)

            # Same if receipt_1 is posted
            Receipt.post([receipt_1])
            self.assertEqual(receipt_1.state, 'posted')
            self.assertEqual(receipt_1.move.state, 'posted')
            self._validate_domain_in(Receipt, Document, receipt_1)

            last_docs_receipt_id = receipt_1.id

            # Group of Receipts
            receipt_grp_1 = create_receipt(
                company, cash, 'in', date)
            receipt_grp_1.cash = Decimal('10.0')
            receipt_grp_2 = create_receipt(
                company, cash, 'in', date)
            receipt_grp_2.cash = Decimal('20.0')

            Receipt.save([receipt_grp_1, receipt_grp_2])
            self.assertEqual(receipt_grp_1.cash, Decimal('10.0'))
            self.assertEqual(receipt_grp_2.cash, Decimal('20.0'))

            receipt_grp_1.cash = Decimal('15.0')
            receipt_grp_2.cash = Decimal('25.0')

            Receipt.save([receipt_grp_1, receipt_grp_2])
            self.assertEqual(receipt_grp_1.cash, Decimal('15.0'))
            self.assertEqual(receipt_grp_2.cash, Decimal('25.0'))

            #####################################
            # Transfer (specially with documents)
            #####################################

            cash_2 = create_cash_bank(
                company, 'Cashier 2', 'cash',
                journal, account_expense, sequence
                )

            with self.assertRaises(UserError):
                # Raise document domain error because
                # documents are not in cash_2
                transfer = Transfer(
                    company=company,
                    date=date,
                    cash_bank_from=cash_2,
                    type_from=cash_2.receipt_types[1],  # out
                    cash_bank_to=cash,
                    type_to=cash.receipt_types[0],  # in
                    documents=Document.search([])
                    )
                transfer.save()

            transfer = Transfer(
                company=company,
                date=date,
                cash=Decimal('10.0'),
                cash_bank_from=cash,
                type_from=cash.receipt_types[1],  # out
                cash_bank_to=cash_2,
                type_to=cash_2.receipt_types[0],  # in
                documents=Document.search([])
                )
            transfer.save()
            self.assertEqual(transfer.total_documents, Decimal('90.0'))
            self.assertEqual(transfer.total, Decimal('100.0'))
            self.assertEqual(transfer.state, 'draft')
            self.assertEqual(transfer.receipt_from, None)
            self.assertEqual(transfer.receipt_to, None)

            Transfer.confirm([transfer])
            self.assertEqual(transfer.state, 'confirmed')
            self.assertEqual(transfer.receipt_from.transfer, transfer)
            self.assertEqual(transfer.receipt_to.transfer, transfer)
            self.assertEqual(transfer.receipt_from.state, 'confirmed')
            self.assertEqual(transfer.receipt_to.state, 'confirmed')

            self._verify_document('abc', transfer.receipt_to.id)
            self._verify_document('def', transfer.receipt_to.id)
            self._verify_document('ghi', transfer.receipt_to.id)

            Transfer.cancel([transfer])
            self.assertEqual(transfer.state, 'cancel')
            self.assertEqual(transfer.receipt_from.transfer, transfer)
            self.assertEqual(transfer.receipt_to.transfer, transfer)
            self.assertEqual(transfer.receipt_from.state, 'cancel')
            self.assertEqual(transfer.receipt_to.state, 'cancel')

            self._verify_document('abc', transfer.receipt_to.id)
            self._verify_document('def', transfer.receipt_to.id)
            self._verify_document('ghi', transfer.receipt_to.id)

            Transfer.draft([transfer])
            self.assertEqual(transfer.state, 'draft')
            self.assertEqual(transfer.receipt_from, None)
            self.assertEqual(transfer.receipt_to, None)

            # Documents go back to the origin receipt
            self._verify_document('abc', last_docs_receipt_id)
            self._verify_document('def', last_docs_receipt_id)
            self._verify_document('ghi', last_docs_receipt_id)

            Transfer.confirm([transfer])
            self.assertEqual(transfer.state, 'confirmed')
            self.assertEqual(transfer.receipt_from.transfer, transfer)
            self.assertEqual(transfer.receipt_to.transfer, transfer)
            self.assertEqual(transfer.receipt_from.state, 'confirmed')
            self.assertEqual(transfer.receipt_to.state, 'confirmed')

            self._verify_document('abc', transfer.receipt_to.id)
            self._verify_document('def', transfer.receipt_to.id)
            self._verify_document('ghi', transfer.receipt_to.id)

            Transfer.post([transfer])
            self.assertEqual(transfer.state, 'posted')
            self.assertEqual(transfer.receipt_from.transfer, transfer)
            self.assertEqual(transfer.receipt_to.transfer, transfer)
            self.assertEqual(transfer.receipt_from.state, 'posted')
            self.assertEqual(transfer.receipt_to.state, 'posted')

            self._verify_document('abc', transfer.receipt_to.id)
            self._verify_document('def', transfer.receipt_to.id)
            self._verify_document('ghi', transfer.receipt_to.id)

            # Convertions

            with self.assertRaises(UserError):
                # Documents are in cash_2
                convertion = Convertion(
                    cash_bank=cash,
                    date=date,
                    documents=Document.search([])
                    )
                convertion.save()

            convertion = Convertion(
                cash_bank=cash_2,
                date=date,
                documents=Document.search([])
                )
            convertion.save()

            Convertion.confirm([convertion])
            self.assertEqual(convertion.state, 'confirmed')
            docs = Document.search([])
            for doc in docs:
                self.assertEqual(doc.convertion.id, convertion.id)

            Convertion.cancel([convertion])
            self.assertEqual(convertion.state, 'cancel')
            docs = Document.search([])
            for doc in docs:
                self.assertEqual(doc.convertion.id, convertion.id)

            Convertion.draft([convertion])
            self.assertEqual(convertion.state, 'draft')
            docs = Document.search([])
            for doc in docs:
                self.assertEqual(doc.convertion, None)
Beispiel #21
0
    def test_purchase_price(self):
        'Test purchase price'
        pool = Pool()
        Account = pool.get('account.account')
        Template = pool.get('product.template')
        Product = pool.get('product.product')
        Uom = pool.get('product.uom')
        ProductSupplier = pool.get('purchase.product_supplier')
        Party = pool.get('party.party')

        company = create_company()
        with set_company(company):
            create_chart(company)

            receivable, = Account.search([
                ('kind', '=', 'receivable'),
                ('company', '=', company.id),
            ])
            payable, = Account.search([
                ('kind', '=', 'payable'),
                ('company', '=', company.id),
            ])

            kg, = Uom.search([('name', '=', 'Kilogram')])
            g, = Uom.search([('name', '=', 'Gram')])

            template, = Template.create([{
                'name': 'Product',
                'default_uom': g.id,
                'purchase_uom': kg.id,
                'list_price': Decimal(5),
                'cost_price': Decimal(2),
                'products': [('create', [{}])],
            }])
            product, = template.products

            supplier, = Party.create([{
                'name': 'Supplier',
                'account_receivable': receivable.id,
                'account_payable': payable.id,
            }])
            product_supplier, = ProductSupplier.create([{
                'product':
                template.id,
                'party':
                supplier.id,
                'prices': [('create', [{
                    'sequence': 1,
                    'quantity': 1,
                    'unit_price': Decimal(3000),
                }, {
                    'sequence': 2,
                    'quantity': 2,
                    'unit_price': Decimal(2500),
                }])],
            }])

            prices = Product.get_purchase_price([product], quantity=100)
            self.assertEqual(prices, {product.id: Decimal(2)})
            prices = Product.get_purchase_price([product], quantity=1500)
            self.assertEqual(prices, {product.id: Decimal(2)})

            with Transaction().set_context(uom=kg.id):
                prices = Product.get_purchase_price([product], quantity=0.5)
                self.assertEqual(prices, {product.id: Decimal(2000)})
                prices = Product.get_purchase_price([product], quantity=1.5)
                self.assertEqual(prices, {product.id: Decimal(2000)})

            with Transaction().set_context(supplier=supplier.id):
                prices = Product.get_purchase_price([product], quantity=100)
                self.assertEqual(prices, {product.id: Decimal(2)})
                prices = Product.get_purchase_price([product], quantity=1500)
                self.assertEqual(prices, {product.id: Decimal(3)})
                prices = Product.get_purchase_price([product], quantity=3000)
                self.assertEqual(prices, {product.id: Decimal('2.5')})

            with Transaction().set_context(uom=kg.id, supplier=supplier.id):
                prices = Product.get_purchase_price([product], quantity=0.5)
                self.assertEqual(prices, {product.id: Decimal(2000)})
                prices = Product.get_purchase_price([product], quantity=1.5)
                self.assertEqual(prices, {product.id: Decimal(3000)})
                prices = Product.get_purchase_price([product], quantity=3)
                self.assertEqual(prices, {product.id: Decimal(2500)})
Beispiel #22
0
    def test_account_used(self):
        'Test account used'
        pool = Pool()
        ProductTemplate = pool.get('product.template')
        ProductCategory = pool.get('product.category')
        Uom = pool.get('product.uom')
        Account = pool.get('account.account')

        company = create_company()
        with set_company(company):
            create_chart(company)

            unit, = Uom.search([
                ('name', '=', 'Unit'),
            ])
            account_expense, = Account.search([
                ('type.expense', '=', True),
            ])

            # raise when empty
            template = ProductTemplate(
                name='Product',
                list_price=Decimal(10),
                default_uom=unit.id,
                products=[],
            )
            template.save()

            with self.assertRaisesRegex(UserError,
                                        'Account Category.*Product'):
                template.account_expense_used

            # with account on category
            category = ProductCategory(name='Category',
                                       accounting=True,
                                       account_expense=None)
            category.save()
            template.account_category = category
            template.save()

            with self.assertRaisesRegex(UserError, 'Account Expense.*Product'):
                template.account_expense_used

            category.account_expense = account_expense
            category.save()

            self.assertEqual(template.account_expense_used, account_expense)

            # with account on grant category
            parent_category = ProductCategory(name='Parent Category',
                                              account_expense=account_expense,
                                              accounting=True)
            parent_category.save()
            category.account_expense = None
            category.account_parent = True
            category.parent = parent_category
            category.save()

            self.assertEqual(template.account_expense_used, account_expense)
            self.assertEqual(category.account_expense_used, account_expense)

            # raise only at direct usage
            categories = ProductCategory.create([{
                'name':
                'Category 1',
                'accounting':
                True,
                'account_expense':
                account_expense.id,
            }, {
                'name': 'Category 2',
                'accounting': True,
                'account_expense': None,
            }])

            self.assertEqual(categories[0].account_expense_used.id,
                             account_expense.id)

            with self.assertRaisesRegex(UserError,
                                        'Account Expense.*Category 2'):
                categories[1].account_expense_used
Beispiel #23
0
    def test_check_credit_limit(self):
        'Test check_credit_limit'
        pool = Pool()
        Account = pool.get('account.account')
        Move = pool.get('account.move')
        Journal = pool.get('account.journal')
        Party = pool.get('party.party')
        Sale = pool.get('sale.sale')
        PaymentTerm = pool.get('account.invoice.payment_term')
        Configuration = pool.get('account.configuration')
        FiscalYear = pool.get('account.fiscalyear')
        Invoice = pool.get('account.invoice')

        company = create_company()
        with set_company(company):
            create_chart(company)
            fiscalyear = set_invoice_sequences(get_fiscalyear(company))
            fiscalyear.save()
            FiscalYear.create_period([fiscalyear])
            period = fiscalyear.periods[0]

            receivable, = Account.search([
                ('type.receivable', '=', True),
            ])
            revenue, = Account.search([
                ('type.revenue', '=', True),
            ])
            journal, = Journal.search([], limit=1)
            party, = Party.create([{
                'name': 'Party',
                'addresses': [
                    ('create', [{}]),
                ],
                'credit_limit_amount': Decimal('100'),
            }])
            Move.create([{
                'journal':
                journal.id,
                'period':
                period.id,
                'date':
                period.start_date,
                'lines': [
                    ('create', [{
                        'debit': Decimal('100'),
                        'account': receivable.id,
                        'party': party.id,
                    }, {
                        'credit': Decimal('100'),
                        'account': revenue.id,
                    }]),
                ],
            }])
            payment_term, = PaymentTerm.create([{
                'name':
                'Test',
                'lines': [('create', [{
                    'type': 'remainder',
                }])],
            }])
            config = Configuration(1)
            config.default_category_account_revenue = revenue
            config.save()
            sale, = Sale.create([{
                'party':
                party.id,
                'company':
                company.id,
                'payment_term':
                payment_term.id,
                'currency':
                company.currency.id,
                'invoice_address':
                party.addresses[0].id,
                'shipment_address':
                party.addresses[0].id,
                'lines': [
                    ('create', [{
                        'description': 'Test',
                        'quantity': 1,
                        'unit_price': Decimal('50'),
                    }]),
                ],
            }])
            self.assertEqual(party.credit_amount, Decimal('100'))
            Sale.quote([sale])
            # Test limit reaches
            self.assertRaises(UserWarning, Sale.confirm, [sale])
            self.assertEqual(party.credit_amount, Decimal('100'))
            # Increase limit
            party.credit_limit_amount = Decimal('200')
            party.save()
            # process should work
            Sale.confirm([sale])
            self.assertEqual(sale.state, 'confirmed')
            self.assertEqual(party.credit_amount, Decimal('150'))

            # Process
            Sale.process([sale])
            # Decrease limit
            party.credit_limit_amount = Decimal('100')
            party.save()
            # process should still work as sale is already processing
            Sale.process([sale])

            # Increase quantity invoiced does not change the credit amount
            invoice, = sale.invoices
            invoice_line, = invoice.lines
            invoice_line.quantity += 1
            invoice_line.save()
            Invoice.post([invoice])
            self.assertEqual(party.credit_amount, Decimal('150'))
Beispiel #24
0
 def test_account_chart(self):
     "Test creation of chart of accounts"
     company = create_company()
     with set_company(company):
         create_chart(company, tax=True)
    def test_account_debit_credit(self):
        'Test account debit/credit'
        pool = Pool()
        Party = pool.get('party.party')
        AnalyticAccount = pool.get('analytic_account.account')
        Journal = pool.get('account.journal')
        Account = pool.get('account.account')
        Move = pool.get('account.move')
        transaction = Transaction()

        party = Party(name='Party')
        party.save()
        company = create_company()
        with set_company(company):
            root, = AnalyticAccount.create([{
                        'type': 'root',
                        'name': 'Root',
                        }])
            analytic_account, = AnalyticAccount.create([{
                        'type': 'normal',
                        'name': 'Analytic Account',
                        'parent': root.id,
                        'root': root.id,
                        }])
            create_chart(company)
            fiscalyear = get_fiscalyear(company)
            fiscalyear.save()
            fiscalyear.create_period([fiscalyear])
            period = fiscalyear.periods[0]
            journal_revenue, = Journal.search([
                    ('code', '=', 'REV'),
                    ])
            journal_expense, = Journal.search([
                    ('code', '=', 'EXP'),
                    ])
            revenue, = Account.search([
                    ('kind', '=', 'revenue'),
                    ])
            receivable, = Account.search([
                    ('kind', '=', 'receivable'),
                    ])
            expense, = Account.search([
                    ('kind', '=', 'expense'),
                    ])
            payable, = Account.search([
                    ('kind', '=', 'payable'),
                    ])

            first_account_line = {
                'account': revenue.id,
                'credit': Decimal(100),
                'analytic_lines': [
                    ('create', [{
                                'account': analytic_account.id,
                                'name': 'Analytic Line',
                                'credit': Decimal(100),
                                'debit': Decimal(0),
                                'journal': journal_revenue.id,
                                'date': period.start_date,
                                }])
                    ]}
            second_account_line = {
                'account': expense.id,
                'debit': Decimal(30),
                'analytic_lines': [
                    ('create', [{
                                'account': analytic_account.id,
                                'name': 'Analytic Line',
                                'debit': Decimal(30),
                                'credit': Decimal(0),
                                'journal': journal_expense.id,
                                'date': period.start_date,
                                }])
                    ]}
            # Create some moves
            vlist = [{
                    'period': period.id,
                    'journal': journal_revenue.id,
                    'date': period.start_date,
                    'lines': [
                        ('create', [first_account_line, {
                                    'account': receivable.id,
                                    'debit': Decimal(100),
                                    'party': party.id,
                                    }]),
                        ],
                    }, {
                    'period': period.id,
                    'journal': journal_expense.id,
                    'date': period.start_date,
                    'lines': [
                        ('create', [second_account_line, {
                                    'account': payable.id,
                                    'credit': Decimal(30),
                                    'party': party.id,
                                    }]),
                        ],
                    },
                ]
            Move.create(vlist)

            self.assertEqual((analytic_account.debit, analytic_account.credit),
                (Decimal(30), Decimal(100)))
            self.assertEqual(analytic_account.balance, Decimal(70))

            with transaction.set_context(start_date=period.end_date):
                analytic_account = AnalyticAccount(analytic_account.id)
                self.assertEqual((analytic_account.debit,
                        analytic_account.credit),
                    (Decimal(0), Decimal(0)))
                self.assertEqual(analytic_account.balance, Decimal(0))

            with transaction.set_context(end_date=period.end_date):
                analytic_account = AnalyticAccount(analytic_account.id)
                self.assertEqual((analytic_account.debit,
                        analytic_account.credit),
                    (Decimal(30), Decimal(100)))
                self.assertEqual(analytic_account.balance, Decimal(70))
Beispiel #26
0
    def _test_analytic_line_state(self):
        pool = Pool()
        Party = pool.get('party.party')
        AnalyticAccount = pool.get('analytic_account.account')
        AnalyticLine = pool.get('analytic_account.line')
        Journal = pool.get('account.journal')
        Account = pool.get('account.account')
        Move = pool.get('account.move')
        MoveLine = pool.get('account.move.line')

        party = Party(name='Party')
        party.save()
        company = create_company()
        with set_company(company):
            root, = AnalyticAccount.create([{
                'type': 'root',
                'name': 'Root',
            }])
            analytic_account1, analytic_account2 = AnalyticAccount.create([{
                'type':
                'normal',
                'name':
                'Analytic Account 1',
                'parent':
                root.id,
                'root':
                root.id,
            }, {
                'type':
                'normal',
                'name':
                'Analytic Account 2',
                'parent':
                root.id,
                'root':
                root.id,
            }])
            create_chart(company)
            fiscalyear = get_fiscalyear(company)
            fiscalyear.save()
            fiscalyear.create_period([fiscalyear])
            period = fiscalyear.periods[0]
            journal_expense, = Journal.search([
                ('code', '=', 'EXP'),
            ])
            expense, = Account.search([
                ('type.expense', '=', True),
            ])
            payable, = Account.search([
                ('type.payable', '=', True),
            ])

            move = Move()
            move.period = period
            move.journal = journal_expense
            move.date = period.start_date
            move.lines = [
                MoveLine(account=expense, debit=Decimal(100)),
                MoveLine(account=payable, credit=Decimal(100), party=party),
            ]
            move.save()
            Move.post([move])

            expense_line, = [l for l in move.lines if l.account == expense]
            payable_line, = [l for l in move.lines if l.account == payable]

            self.assertEqual(expense_line.analytic_state, 'draft')
            self.assertEqual(payable_line.analytic_state, 'valid')

            expense_line.analytic_lines = [
                AnalyticLine(account=analytic_account1,
                             debit=Decimal(50),
                             date=period.start_date),
                AnalyticLine(account=analytic_account2,
                             debit=Decimal(50),
                             date=period.start_date),
            ]
            expense_line.save()

            self.assertEqual(expense_line.analytic_state, 'valid')
    def test_invoice_generation(self):
        'Test invoice generation'

        pool = Pool()
        Account = pool.get('account.account')
        FiscalYear = pool.get('account.fiscalyear')
        Invoice = pool.get('account.invoice')
        InvoiceLine = pool.get('account.invoice.line')
        Party = pool.get('party.party')
        PaymentTerm = pool.get('account.invoice.payment_term')
        ProductUom = pool.get('product.uom')
        ProductCategory = pool.get('product.category')
        ProductTemplate = pool.get('product.template')
        Product = pool.get('product.product')
        Tax = pool.get('account.tax')
        Address = pool.get('party.address')
        PartyIdentifier = pool.get('party.identifier')
        Country = pool.get('country.country')
        Subdivision = pool.get('country.subdivision')
        PaymentType = pool.get('account.payment.type')

        country = Country(name='Country', code='ES', code3='ESP')
        country.save()
        subdivision = Subdivision(name='Subdivision',
                                  country=country,
                                  code='SUB',
                                  type='province')
        subdivision.save()

        company = create_company()
        currency = create_currency('EUR')
        add_currency_rate(currency, 1.0)

        tax_identifier = PartyIdentifier()
        tax_identifier.type = 'eu_vat'
        tax_identifier.code = 'BE0897290877'
        company.header = 'Report Header'
        company.party.name = 'Seller'
        company.party.identifiers = [tax_identifier]
        company.party.facturae_person_type = 'J'
        company.party.facturae_residence_type = 'R'
        company.party.save()
        company.save()

        # Save certificate into company
        with open(os.path.join(CURRENT_PATH, 'certificate.pfx'),
                  'rb') as cert_file:
            company.facturae_certificate = cert_file.read()

        payment_term, = PaymentTerm.create([{
            'name':
            '20 days, 40 days',
            'lines': [('create', [{
                'sequence':
                0,
                'type':
                'percent',
                'divisor':
                2,
                'ratio':
                Decimal('.5'),
                'relativedeltas': [
                    ('create', [
                        {
                            'days': 20,
                        },
                    ]),
                ],
            }, {
                'sequence':
                1,
                'type':
                'remainder',
                'relativedeltas': [
                    ('create', [
                        {
                            'days': 40,
                        },
                    ]),
                ],
            }])]
        }])

        with set_company(company):
            create_chart(company, tax=True)

            fiscalyear = set_invoice_sequences(get_fiscalyear(company))
            fiscalyear.save()
            FiscalYear.create_period([fiscalyear])

            payment_receivable, = PaymentType.create([{
                'name': 'Payment Receivable',
                'kind': 'receivable',
                'company': company.id,
                'facturae_type': '01',
            }])
            revenue, = Account.search([('type.revenue', '=', True)])
            expense, = Account.search([('type.expense', '=', True)])
            tax_account, = Account.search([
                ('name', '=', 'Main Tax'),
            ])
            with Transaction().set_user(0):
                vat21 = Tax()
                vat21.name = vat21.description = '21% VAT'
                vat21.type = 'percentage'
                vat21.rate = Decimal('0.21')
                vat21.invoice_account = tax_account
                vat21.report_type = '05'
                vat21.credit_note_account = tax_account

            vat21.save()

            company_address, = company.party.addresses
            company_address.street = 'street'
            company_address.zip = '08201'
            company_address.city = 'City'
            company_address.subdivision = subdivision
            company_address.country = country
            company_address.save()
            party = Party(name='Buyer')
            party.facturae_person_type = 'J'
            party.facturae_residence_type = 'R'
            tax_identifier = PartyIdentifier()
            tax_identifier.type = 'eu_vat'
            tax_identifier.code = 'BE0897290877'
            party.identifiers = [tax_identifier]
            party.save()

            address_dict = {
                'party': party.id,
                'street': 'St sample, 15',
                'city': 'City',
                'zip': '08201',
                'subdivision': subdivision.id,
                'country': country.id,
            }

            address, = Address.create([address_dict])

            term, = PaymentTerm.create([{
                'name':
                'Payment term',
                'lines': [('create', [{
                    'type':
                    'remainder',
                    'relativedeltas': [('create', [{
                        'sequence': 0,
                        'days': 0,
                        'months': 0,
                        'weeks': 0,
                    }])],
                }])],
            }])

            account_category = ProductCategory()
            account_category.name = 'Account Category'
            account_category.accounting = True
            account_category.account_expense = expense
            account_category.account_revenue = revenue
            account_category.customer_taxes = [vat21]
            account_category.save()

            unit, = ProductUom.search([('name', '=', 'Unit')])
            template = ProductTemplate()
            template.name = 'product'
            template.default_uom = unit
            template.type = 'service'
            template.list_price = Decimal('40')
            template.account_category = account_category
            template.save()
            product = Product()
            product.template = template
            product.save()

            currency = create_currency('Eur')
            add_currency_rate(currency, 1)

            with Transaction().set_user(0):
                invoice = Invoice()
                invoice.type = 'out'
                invoice.on_change_type()
                invoice.party = party
                invoice.on_change_party()
                invoice.payment_type = payment_receivable
                invoice.payment_term = term
                invoice.currency = currency
                invoice.company = company
                invoice.payment_term = invoice.on_change_with_payment_term()
                invoice.account = invoice.on_change_with_account()

                line1 = InvoiceLine()
                line1.product = product
                line1.on_change_product()
                line1.on_change_account()
                line1.quantity = 5
                line1.unit_price = Decimal('40')

                line2 = InvoiceLine()
                line2.account = revenue
                line2.on_change_account()
                line2.product = product
                line2.on_change_product()
                line2.description = 'Test'
                line2.quantity = 1
                line2.unit_price = Decimal(20)

                invoice.lines = [line1, line2]
                invoice.on_change_lines()

                invoice.save()
                Invoice.post([invoice])

            Invoice.generate_facturae_default([invoice], 'privatepassword')
Beispiel #28
0
    def create_product_supplier_day(self, lead_time, weekday):
        '''
        Create a Product with a Product Supplier Day

        :param lead_time: minimal timedelta needed to supply
        :param weekday: supply day of the week (0 - 6)
        :return: the id of the Product Supplier Day
        '''
        pool = Pool()
        Uom = pool.get('product.uom')
        UomCategory = pool.get('product.uom.category')
        Template = pool.get('product.template')
        Product = pool.get('product.product')
        Party = pool.get('party.party')
        Account = pool.get('account.account')
        ProductSupplier = pool.get('purchase.product_supplier')
        ProductSupplierDay = pool.get('purchase.product_supplier.day')
        Day = pool.get('ir.calendar.day')

        uom_category, = UomCategory.create([{'name': 'Test'}])
        uom, = Uom.create([{
            'name': 'Test',
            'symbol': 'T',
            'category': uom_category.id,
            'rate': 1.0,
            'factor': 1.0,
        }])
        template, = Template.create([{
            'name': 'ProductTest',
            'default_uom': uom.id,
            'list_price': Decimal(0),
        }])
        product, = Product.create([{
            'template': template.id,
        }])
        company = create_company()
        with set_company(company):
            create_chart(company)
            receivable, = Account.search([
                ('type.receivable', '=', True),
                ('company', '=', company.id),
            ])
            payable, = Account.search([
                ('type.payable', '=', True),
                ('company', '=', company.id),
            ])
            supplier, = Party.create([{
                'name': 'supplier',
                'account_receivable': receivable.id,
                'account_payable': payable.id,
            }])
            product_supplier, = ProductSupplier.create([{
                'template': template.id,
                'company': company.id,
                'party': supplier.id,
                'lead_time': lead_time,
            }])
            if weekday is not None:
                day, = Day.search([('index', '=', weekday)])
                ProductSupplierDay.create([{
                    'product_supplier':
                    product_supplier.id,
                    'day':
                    day.id,
                }])
            return product_supplier
    def test_check_credit_limit(self):
        'Test check_credit_limit'
        pool = Pool()
        Account = pool.get('account.account')
        Move = pool.get('account.move')
        Journal = pool.get('account.journal')
        Party = pool.get('party.party')

        company = create_company()
        with set_company(company):
            create_chart(company)
            fiscalyear = get_fiscalyear(company)
            fiscalyear.save()
            fiscalyear.create_period([fiscalyear])
            period = fiscalyear.periods[0]

            receivable, = Account.search([
                    ('kind', '=', 'receivable'),
                    ])
            revenue, = Account.search([
                    ('kind', '=', 'revenue'),
                    ])
            journal, = Journal.search([], limit=1)
            party, = Party.create([{
                        'name': 'Party',
                        }])
            Move.create([{
                        'journal': journal.id,
                        'period': period.id,
                        'date': period.start_date,
                        'lines': [
                            ('create', [{
                                        'debit': Decimal(100),
                                        'account': receivable.id,
                                        'party': party.id,
                                        }, {
                                        'credit': Decimal(100),
                                        'account': revenue.id,
                                        }]),
                            ],
                        }])
            self.assertEqual(party.credit_amount, Decimal(100))
            self.assertEqual(party.credit_limit_amount, None)
            party.check_credit_limit(Decimal(0))
            party.check_credit_limit(Decimal(0), 'test')
            party.check_credit_limit(Decimal(100))
            party.check_credit_limit(Decimal(100), 'test')
            party.credit_limit_amount = Decimal(0)
            party.save()
            self.assertRaises(UserError, party.check_credit_limit,
                Decimal(0))
            self.assertRaises(UserWarning, party.check_credit_limit,
                Decimal(0), 'test')
            party.credit_limit_amount = Decimal(200)
            party.save()
            party.check_credit_limit(Decimal(0))
            party.check_credit_limit(Decimal(0), 'test')
            self.assertRaises(UserError, party.check_credit_limit,
                Decimal(150))
            self.assertRaises(UserWarning, party.check_credit_limit,
                Decimal(150), 'test')
Beispiel #30
0
    def test_check_credit_limit(self):
        'Test check_credit_limit'
        pool = Pool()
        Account = pool.get('account.account')
        Move = pool.get('account.move')
        Journal = pool.get('account.journal')
        Party = pool.get('party.party')

        company = create_company()
        with set_company(company):
            create_chart(company)
            fiscalyear = get_fiscalyear(company)
            fiscalyear.save()
            fiscalyear.create_period([fiscalyear])
            period = fiscalyear.periods[0]

            receivable, = Account.search([
                ('type.receivable', '=', True),
            ])
            revenue, = Account.search([
                ('type.revenue', '=', True),
            ])
            journal, = Journal.search([], limit=1)
            party, = Party.create([{
                'name': 'Party',
            }])
            Move.create([{
                'journal':
                journal.id,
                'period':
                period.id,
                'date':
                period.start_date,
                'lines': [
                    ('create', [{
                        'debit': Decimal(100),
                        'account': receivable.id,
                        'party': party.id,
                    }, {
                        'credit': Decimal(100),
                        'account': revenue.id,
                    }]),
                ],
            }])
            self.assertEqual(party.credit_amount, Decimal(100))
            self.assertEqual(party.credit_limit_amount, None)
            party.check_credit_limit(Decimal(0))
            party.check_credit_limit(Decimal(0), 'test')
            party.check_credit_limit(Decimal(100))
            party.check_credit_limit(Decimal(100), 'test')
            party.credit_limit_amount = Decimal(0)
            party.save()
            self.assertRaises(UserError, party.check_credit_limit, Decimal(0))
            self.assertRaises(UserWarning, party.check_credit_limit,
                              Decimal(0), 'test')
            party.credit_limit_amount = Decimal(200)
            party.save()
            party.check_credit_limit(Decimal(0))
            party.check_credit_limit(Decimal(0), 'test')
            self.assertRaises(UserError, party.check_credit_limit,
                              Decimal(150))
            self.assertRaises(UserWarning, party.check_credit_limit,
                              Decimal(150), 'test')
    def test_account_used(self):
        'Test account used'
        pool = Pool()
        ProductTemplate = pool.get('product.template')
        ProductCategory = pool.get('product.category')
        Uom = pool.get('product.uom')
        Account = pool.get('account.account')

        company = create_company()
        with set_company(company):
            create_chart(company)

            unit, = Uom.search([
                    ('name', '=', 'Unit'),
                    ])
            account_expense, = Account.search([
                    ('kind', '=', 'expense'),
                    ])

            # raise when empty
            template = ProductTemplate(
                name='test account used',
                list_price=Decimal(10),
                cost_price=Decimal(3),
                default_uom=unit.id,
                )
            template.save()

            self.assertIsNone(template.account_expense)

            with self.assertRaises(UserError):
                template.account_expense_used

            # with account
            template = ProductTemplate(
                name='test account used',
                list_price=Decimal(10),
                cost_price=Decimal(3),
                default_uom=unit.id,
                account_expense=account_expense.id,
                )
            template.save()

            self.assertEqual(template.account_expense, account_expense)
            self.assertEqual(template.account_expense_used, account_expense)

            # with account on category
            category = ProductCategory(name='test account used',
                account_expense=account_expense)
            category.save()
            template.account_expense = None
            template.account_category = True
            template.category = category
            template.save()

            self.assertIsNone(template.account_expense)
            self.assertEqual(template.account_expense_used, account_expense)

            # with account on grant category
            parent_category = ProductCategory(name='parent account used',
                account_expense=account_expense)
            parent_category.save()
            category.account_expense = None
            category.account_parent = True
            category.parent = parent_category
            category.save()

            self.assertIsNone(category.account_expense)
            self.assertEqual(template.account_expense_used, account_expense)
            self.assertEqual(category.account_expense_used, account_expense)

            # raise only at direct usage
            templates = ProductTemplate.create([{
                        'name': 'test with account',
                        'list_price': Decimal(10),
                        'cost_price': Decimal(3),
                        'default_uom': unit.id,
                        'account_expense': account_expense.id,
                        }, {
                        'name': 'test without account',
                        'list_price': Decimal(10),
                        'cost_price': Decimal(3),
                        'default_uom': unit.id,
                        'account_expense': None,
                        }])

            self.assertEqual(templates[0].account_expense_used.id,
                account_expense.id)

            with self.assertRaises(UserError):
                templates[1].account_expense_used
    def test_reconciliation(self):
        pool = Pool()
        Account = pool.get('account.account')
        Receipt = pool.get('cash_bank.receipt')
        Reconciliation = pool.get('cash_bank.reconciliation')
        Line = pool.get('cash_bank.reconciliation.line')
        Config = pool.get('cash_bank.configuration')

        party = self._create_party('Party test', None)

        transaction = Transaction()

        company = create_company()
        with set_company(company):
            create_chart(company)
            create_fiscalyear(company)

            account_transfer, = Account.search([
                ('name', '=', 'Main Expense'),
            ])
            account_cash, = Account.search([
                ('name', '=', 'Main Cash'),
            ])
            account_revenue, = Account.search([
                ('name', '=', 'Main Revenue'),
            ])
            account_expense, = Account.search([
                ('name', '=', 'Main Expense'),
            ])

            config = Config(account_transfer=account_transfer)
            config.save()

            journal = create_journal(company, 'journal_cash')

            sequence = create_sequence('Cash/Bank Sequence',
                                       'cash_bank.receipt', company)
            sequence_convertion = create_sequence('Cash/Bank Convertion',
                                                  'cash_bank.convertion',
                                                  company)
            sequence_reconciliation = create_sequence(
                'Cash/Bank Reconciliation', 'cash_bank.reconciliation',
                company)

            config.convertion_seq = sequence_convertion
            config.reconciliation_seq = sequence_reconciliation
            config.save()

            _, bank_account = create_bank_account(
                party_bank=self._create_party('Party Bank', None),
                party_owner=company.party)

            bank = create_cash_bank(company, 'Main Bank', 'bank', journal,
                                    account_cash, sequence, bank_account)
            self.assertEqual(len(bank.receipt_types), 2)

            date = datetime.date.today()

            rcps = [
                self._get_receipt(company, bank, 'in', date, Decimal('100.0'),
                                  account_revenue),
                self._get_receipt(company, bank, 'in', date, Decimal('200.0'),
                                  account_revenue),
                self._get_receipt(company, bank, 'in', date, Decimal('300.0'),
                                  account_revenue),
                self._get_receipt(company, bank, 'in', date, Decimal('400.0'),
                                  account_revenue),
                self._get_receipt(company, bank, 'out', date, Decimal('10.0'),
                                  account_expense, party),
                self._get_receipt(company, bank, 'out', date, Decimal('20.0'),
                                  account_expense, party),
            ]
            Receipt.save(rcps)
            Receipt.confirm(rcps)

            recon = Reconciliation(
                company=company,
                cash_bank=bank,
                date=date,
                date_start=date,
                date_end=date,
                bank_balance=Decimal(600.0),
                last_bank_balance=Decimal(0.0),
            )
            recon.save()

            Reconciliation.complete_lines([recon])
            self.assertEqual(len(recon.lines), 6)

            transaction.commit()

            with self.assertRaises(UserError):
                # Diff != 0. There is no lines checked
                Reconciliation.confirm([recon])
            transaction.rollback()

            lines = Line.search([
                ('reconciliation', '=', recon.id),
                ('amount', 'in',
                 [Decimal('100.0'),
                  Decimal('200.0'),
                  Decimal('300.0')]),
            ])
            self.assertEqual(len(lines), 3)
            for line in lines:
                line.check = True
            Line.save(lines)
            recon.save()

            self.assertEqual(recon.diff, Decimal('0.0'))
            transaction.commit()

            with self.assertRaises(UserError):
                # Account move lines are not posted
                Reconciliation.confirm([recon])
            transaction.rollback()

            Receipt.post(rcps)
            Reconciliation.confirm([recon])

            # Account moves can not be posted if a confirmed reconciliation
            # invalidates them

            # Same date
            receipt = self._get_receipt(company, bank, 'in', date,
                                        Decimal('99.0'), account_revenue)
            receipt.save()
            Receipt.confirm([receipt])

            transaction.commit()
            with self.assertRaises(UserError):
                Receipt.post([receipt])
            transaction.rollback()

            # Date before
            new_date = date - datetime.timedelta(days=1)
            receipt = self._get_receipt(company, bank, 'in', new_date,
                                        Decimal('99.0'), account_revenue)
            receipt.save()
            Receipt.confirm([receipt])

            transaction.commit()
            with self.assertRaises(UserError):
                Receipt.post([receipt])
            transaction.rollback()

            # Date OK
            new_date = date + datetime.timedelta(days=1)
            receipt = self._get_receipt(company, bank, 'in', new_date,
                                        Decimal('99.0'), account_revenue)
            receipt.save()
            Receipt.confirm([receipt])
            Receipt.post([receipt])