first commit

This commit is contained in:
root
2026-03-14 09:42:12 +00:00
commit 0adbd20c2c
10991 changed files with 1646955 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.

View File

@@ -0,0 +1,703 @@
=============
Sale Scenario
=============
Imports::
>>> from decimal import Decimal
>>> from proteus import Model, Report, Wizard
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, create_tax, get_accounts)
>>> from trytond.modules.account_invoice.tests.tools import (
... create_payment_term, set_fiscalyear_invoice_sequences)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual, set_user
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
>>> Employee = Model.get('company.employee')
>>> Party = Model.get('party.party')
>>> User = Model.get('res.user')
Set employee::
>>> employee_party = Party(name="Employee")
>>> employee_party.save()
>>> employee = Employee(party=employee_party)
>>> employee.save()
>>> user = User(config.user)
>>> user.employees.append(employee)
>>> user.employee = employee
>>> user.save()
>>> set_user(user.id)
Create fiscal year::
>>> fiscalyear = set_fiscalyear_invoice_sequences(create_fiscalyear())
>>> fiscalyear.click('create_period')
Get accounts::
>>> accounts = get_accounts()
>>> revenue = accounts['revenue']
>>> expense = accounts['expense']
>>> cash = accounts['cash']
>>> Journal = Model.get('account.journal')
>>> PaymentMethod = Model.get('account.invoice.payment.method')
>>> cash_journal, = Journal.find([('type', '=', 'cash')])
>>> cash_journal.save()
>>> payment_method = PaymentMethod()
>>> payment_method.name = 'Cash'
>>> payment_method.journal = cash_journal
>>> payment_method.credit_account = cash
>>> payment_method.debit_account = cash
>>> payment_method.save()
Create tax::
>>> tax = create_tax(Decimal('.10'))
>>> tax.save()
Create parties::
>>> Party = Model.get('party.party')
>>> supplier = Party(name='Supplier')
>>> supplier.save()
>>> customer = Party(name='Customer')
>>> customer.save()
Create account categories::
>>> ProductCategory = Model.get('product.category')
>>> account_category = ProductCategory(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_expense = expense
>>> account_category.account_revenue = revenue
>>> account_category.save()
>>> account_category_tax, = account_category.duplicate()
>>> account_category_tax.customer_taxes.append(tax)
>>> account_category_tax.save()
Create product::
>>> ProductUom = Model.get('product.uom')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> ProductTemplate = Model.get('product.template')
>>> template = ProductTemplate()
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.salable = True
>>> template.list_price = Decimal('10')
>>> template.account_category = account_category_tax
>>> template.save()
>>> product, = template.products
>>> template = ProductTemplate()
>>> template.name = 'service'
>>> template.default_uom = unit
>>> template.type = 'service'
>>> template.salable = True
>>> template.list_price = Decimal('30')
>>> template.account_category = account_category
>>> template.save()
>>> service, = template.products
Create payment term::
>>> payment_term = create_payment_term()
>>> payment_term.save()
Create an Inventory::
>>> Inventory = Model.get('stock.inventory')
>>> Location = Model.get('stock.location')
>>> storage, = Location.find([
... ('code', '=', 'STO'),
... ])
>>> inventory = Inventory()
>>> inventory.location = storage
>>> inventory_line = inventory.lines.new(product=product)
>>> inventory_line.quantity = 100.0
>>> inventory_line.expected_quantity = 0.0
>>> inventory.click('confirm')
>>> inventory.state
'done'
Sale 5 products::
>>> Sale = Model.get('sale.sale')
>>> SaleLine = Model.get('sale.line')
>>> sale = Sale()
>>> sale.party = customer
>>> sale.payment_term = payment_term
>>> sale.invoice_method = 'order'
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.product = product
>>> sale_line.quantity = 2.0
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.type = 'comment'
>>> sale_line.description = 'Comment'
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.product = product
>>> sale_line.quantity = 3.0
>>> sale.click('quote')
>>> sale.untaxed_amount, sale.tax_amount, sale.total_amount
(Decimal('50.00'), Decimal('5.00'), Decimal('55.00'))
>>> assertEqual(sale.quoted_by, employee)
>>> sale.click('confirm')
>>> sale.untaxed_amount, sale.tax_amount, sale.total_amount
(Decimal('50.00'), Decimal('5.00'), Decimal('55.00'))
>>> assertEqual(sale.confirmed_by, employee)
>>> sale.state
'processing'
>>> sale.shipment_state
'waiting'
>>> sale.invoice_state
'pending'
>>> len(sale.shipments), len(sale.shipment_returns), len(sale.invoices)
(1, 0, 1)
>>> invoice, = sale.invoices
>>> assertEqual(invoice.origins, sale.rec_name)
>>> shipment, = sale.shipments
>>> assertEqual(shipment.origins, sale.rec_name)
Invoice line must be linked to stock move::
>>> invoice_line1, invoice_line2 = sorted(
... invoice.lines, key=lambda l: l.quantity or 0)
>>> stock_move1, stock_move2 = sorted(shipment.outgoing_moves,
... key=lambda m: m.quantity or 0)
>>> assertEqual(invoice_line1.stock_moves, [stock_move1])
>>> assertEqual(stock_move1.invoice_lines, [invoice_line1])
>>> assertEqual(invoice_line2.stock_moves, [stock_move2])
>>> assertEqual(stock_move2.invoice_lines, [invoice_line2])
Check actual quantity::
>>> for line in sale.lines:
... assertEqual(line.quantity, line.actual_quantity)
Post invoice and check no new invoices::
>>> for invoice in sale.invoices:
... invoice.click('post')
>>> sale.reload()
>>> len(sale.shipments), len(sale.shipment_returns), len(sale.invoices)
(1, 0, 1)
>>> sale.invoice_state
'awaiting payment'
Testing the report::
>>> sale_report = Report('sale.sale')
>>> ext, _, _, name = sale_report.execute([sale], {})
>>> ext
'odt'
>>> name
'Sale-1'
Sale 5 products with an invoice method 'on shipment'::
>>> Sale = Model.get('sale.sale')
>>> SaleLine = Model.get('sale.line')
>>> sale = Sale()
>>> sale.party = customer
>>> sale.payment_term = payment_term
>>> sale.invoice_method = 'shipment'
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.product = product
>>> sale_line.quantity = 2.0
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.type = 'comment'
>>> sale_line.description = 'Comment'
>>> sale_line = SaleLine()
>>> sale.lines.append(sale_line)
>>> sale_line.product = product
>>> sale_line.quantity = 3.0
>>> sale.click('quote')
>>> sale.click('confirm')
>>> sale.state
'processing'
>>> sale.shipment_state
'waiting'
>>> sale.invoice_state
'none'
>>> sale.reload()
>>> len(sale.shipments), len(sale.shipment_returns), len(sale.invoices)
(1, 0, 0)
Not yet linked to invoice lines::
>>> shipment, = sale.shipments
>>> stock_move1, stock_move2 = sorted(shipment.outgoing_moves,
... key=lambda m: m.quantity or 0)
>>> len(stock_move1.invoice_lines)
0
>>> len(stock_move2.invoice_lines)
0
Validate Shipments::
>>> shipment.click('assign_try')
>>> shipment.click('pick')
>>> shipment.click('pack')
>>> shipment.click('do')
Open customer invoice::
>>> sale.reload()
>>> sale.invoice_state
'pending'
>>> invoice, = sale.invoices
>>> invoice.type
'out'
>>> invoice_line1, invoice_line2 = sorted(invoice.lines,
... key=lambda l: l.quantity or 0)
>>> for line in invoice.lines:
... line.quantity = 1
... line.save()
>>> invoice.click('post')
Invoice lines must be linked to each stock moves::
>>> assertEqual(invoice_line1.stock_moves, [stock_move1])
>>> assertEqual(invoice_line2.stock_moves, [stock_move2])
Check second invoices::
>>> sale.reload()
>>> len(sale.invoices)
2
>>> sum(l.quantity for i in sale.invoices for l in i.lines)
5.0
Sale 5 products with shipment method 'on invoice'::
>>> sale = Sale()
>>> sale.party = customer
>>> sale.payment_term = payment_term
>>> sale.shipment_method = 'invoice'
>>> sale_line = sale.lines.new()
>>> sale_line.product = product
>>> sale_line.quantity = 5.0
>>> sale.click('quote')
>>> sale.click('confirm')
>>> sale.state
'processing'
>>> sale.shipment_state
'none'
>>> sale.invoice_state
'pending'
>>> len(sale.shipments), len(sale.shipment_returns), len(sale.invoices)
(0, 0, 1)
Not yet linked to stock moves::
>>> invoice, = sale.invoices
>>> invoice_line, = invoice.lines
>>> len(invoice_line.stock_moves)
0
Post and Pay Invoice for 4 products::
>>> invoice_line, = invoice.lines
>>> invoice_line.quantity
5.0
>>> invoice_line.quantity = 4.0
>>> invoice.click('post')
>>> pay = invoice.click('pay')
>>> pay.form.payment_method = payment_method
>>> pay.execute('choice')
>>> invoice.reload()
>>> invoice.state
'paid'
Invoice lines linked to 1 move::
>>> invoice_line, = invoice.lines
>>> len(invoice_line.stock_moves)
1
Stock moves must be linked to invoice line::
>>> sale.reload()
>>> shipment, = sale.shipments
>>> shipment.reload()
>>> stock_move, = shipment.outgoing_moves
>>> stock_move.quantity
4.0
>>> assertEqual(stock_move.invoice_lines, [invoice_line])
Ship 3 products::
>>> stock_inventory_move, = shipment.inventory_moves
>>> stock_inventory_move.quantity
4.0
>>> stock_inventory_move.quantity = 3.0
>>> shipment.click('assign_try')
>>> shipment.click('pick')
>>> shipment.click('pack')
>>> shipment.click('do')
>>> shipment.state
'done'
New shipments created::
>>> sale.reload()
>>> len(sale.shipments)
2
Invoice lines linked to new moves::
>>> invoice.reload()
>>> invoice_line, = invoice.lines
>>> len(invoice_line.stock_moves)
2
Create a Return::
>>> return_ = Sale()
>>> return_.party = customer
>>> return_.payment_term = payment_term
>>> return_.invoice_method = 'shipment'
>>> return_line = SaleLine()
>>> return_.lines.append(return_line)
>>> return_line.product = product
>>> return_line.quantity = -4.
>>> return_line = SaleLine()
>>> return_.lines.append(return_line)
>>> return_line.type = 'comment'
>>> return_line.description = 'Comment'
>>> return_.click('quote')
>>> return_.click('confirm')
>>> return_.state
'processing'
>>> return_.shipment_state
'waiting'
>>> return_.invoice_state
'none'
>>> (len(return_.shipments), len(return_.shipment_returns),
... len(return_.invoices))
(0, 1, 0)
Receive Return Shipment for 3 products::
>>> ship_return, = return_.shipment_returns
>>> move_return, = ship_return.incoming_moves
>>> move_return.product.rec_name
'product'
>>> move_return.quantity
4.0
>>> move_return.quantity = 3
>>> ship_return.click('receive')
Check Return::
>>> return_.reload()
>>> return_.shipment_state
'partially shipped'
>>> return_.invoice_state
'pending'
>>> (len(return_.shipments), len(return_.shipment_returns),
... len(return_.invoices))
(0, 2, 1)
Open customer credit note::
>>> credit_note, = return_.invoices
>>> credit_note.type
'out'
>>> len(credit_note.lines)
1
>>> sum(l.quantity for l in credit_note.lines)
-3.0
>>> credit_note.click('post')
Receive Remaining Return Shipment::
>>> return_.reload()
>>> _, ship_return = return_.shipment_returns
>>> move_return, = ship_return.incoming_moves
>>> move_return.product.rec_name
'product'
>>> move_return.quantity
1.0
>>> ship_return.click('receive')
Check Return::
>>> return_.reload()
>>> return_.shipment_state
'sent'
>>> return_.invoice_state
'awaiting payment'
>>> (len(return_.shipments), len(return_.shipment_returns),
... len(return_.invoices))
(0, 2, 2)
Mixing return and sale::
>>> mix = Sale()
>>> mix.party = customer
>>> mix.payment_term = payment_term
>>> mix.invoice_method = 'order'
>>> mixline = SaleLine()
>>> mix.lines.append(mixline)
>>> mixline.product = product
>>> mixline.quantity = 7.
>>> mixline_comment = SaleLine()
>>> mix.lines.append(mixline_comment)
>>> mixline_comment.type = 'comment'
>>> mixline_comment.description = 'Comment'
>>> mixline2 = SaleLine()
>>> mix.lines.append(mixline2)
>>> mixline2.product = product
>>> mixline2.quantity = -2.
>>> mix.click('quote')
>>> mix.click('confirm')
>>> mix.state
'processing'
>>> mix.shipment_state
'waiting'
>>> mix.invoice_state
'pending'
>>> len(mix.shipments), len(mix.shipment_returns), len(mix.invoices)
(1, 1, 1)
Checking Shipments::
>>> mix_return, = mix.shipment_returns
>>> mix_shipment, = mix.shipments
>>> mix_return.click('receive')
>>> move_return, = mix_return.incoming_moves
>>> move_return.product.rec_name
'product'
>>> move_return.quantity
2.0
>>> mix_shipment.click('assign_try')
>>> mix_shipment.click('pick')
>>> mix_shipment.click('pack')
>>> mix_shipment.click('do')
>>> move_shipment, = mix_shipment.outgoing_moves
>>> move_shipment.product.rec_name
'product'
>>> move_shipment.quantity
7.0
Checking the invoice::
>>> mix.reload()
>>> mix_invoice, = mix.invoices
>>> mix_invoice.type
'out'
>>> len(mix_invoice.lines)
2
>>> sorted(l.quantity for l in mix_invoice.lines)
[-2.0, 7.0]
>>> mix_invoice.click('post')
Mixing stuff with an invoice method 'on shipment'::
>>> mix = Sale()
>>> mix.party = customer
>>> mix.payment_term = payment_term
>>> mix.invoice_method = 'shipment'
>>> mixline = SaleLine()
>>> mix.lines.append(mixline)
>>> mixline.product = product
>>> mixline.quantity = 6.
>>> mixline_comment = SaleLine()
>>> mix.lines.append(mixline_comment)
>>> mixline_comment.type = 'comment'
>>> mixline_comment.description = 'Comment'
>>> mixline2 = SaleLine()
>>> mix.lines.append(mixline2)
>>> mixline2.product = product
>>> mixline2.quantity = -3.
>>> mix.click('quote')
>>> mix.click('confirm')
>>> mix.state
'processing'
>>> mix.shipment_state
'waiting'
>>> mix.invoice_state
'none'
>>> len(mix.shipments), len(mix.shipment_returns), len(mix.invoices)
(1, 1, 0)
Checking Shipments::
>>> mix_return, = mix.shipment_returns
>>> mix_shipment, = mix.shipments
>>> mix_return.click('receive')
>>> move_return, = mix_return.incoming_moves
>>> move_return.product.rec_name
'product'
>>> move_return.quantity
3.0
>>> mix_shipment.click('assign_try')
>>> mix_shipment.click('pick')
>>> mix_shipment.click('pack')
>>> move_shipment, = mix_shipment.outgoing_moves
>>> move_shipment.product.rec_name
'product'
>>> move_shipment.quantity
6.0
Sale services::
>>> service_sale = Sale()
>>> service_sale.party = customer
>>> service_sale.payment_term = payment_term
>>> sale_line = service_sale.lines.new()
>>> sale_line.product = service
>>> sale_line.quantity = 1
>>> service_sale.save()
>>> service_sale.click('quote')
>>> service_sale.click('confirm')
>>> service_sale.state
'processing'
>>> service_sale.shipment_state
'none'
>>> service_sale.invoice_state
'pending'
>>> service_invoice, = service_sale.invoices
Pay the service invoice::
>>> service_invoice.click('post')
>>> pay = service_invoice.click('pay')
>>> pay.form.payment_method = payment_method
>>> pay.execute('choice')
>>> service_invoice.reload()
>>> service_invoice.state
'paid'
Check service sale states::
>>> service_sale.reload()
>>> service_sale.invoice_state
'paid'
>>> service_sale.shipment_state
'none'
>>> service_sale.state
'done'
Return sales using the wizard::
>>> sale_to_return = Sale()
>>> sale_to_return.party = customer
>>> sale_to_return.payment_term = payment_term
>>> sale_line = sale_to_return.lines.new()
>>> sale_line.product = service
>>> sale_line.quantity = 1
>>> sale_line = sale_to_return.lines.new()
>>> sale_line.type = 'comment'
>>> sale_line.description = 'Test comment'
>>> sale_to_return.click('quote')
>>> sale_to_return.click('confirm')
>>> sale_to_return.state
'processing'
>>> return_sale = Wizard('sale.return_sale', [sale_to_return])
>>> return_sale.execute('return_')
>>> returned_sale, = Sale.find([
... ('state', '=', 'draft'),
... ])
>>> assertEqual(returned_sale.origin, sale_to_return)
>>> sorted([x.quantity or 0 for x in returned_sale.lines])
[-1.0, 0]
Create a sale to be invoiced on shipment partialy and check correctly linked
to invoices::
>>> sale = Sale()
>>> sale.party = customer
>>> sale.payment_term = payment_term
>>> sale.invoice_method = 'shipment'
>>> line = sale.lines.new()
>>> line.product = product
>>> line.quantity = 10.0
>>> sale.click('quote')
>>> sale.click('confirm')
>>> shipment, = sale.shipments
>>> for move in shipment.inventory_moves:
... move.quantity = 5.0
>>> shipment.click('assign_try')
>>> shipment.click('pick')
>>> shipment.click('pack')
>>> shipment.click('do')
>>> sale.reload()
>>> invoice, = sale.invoices
>>> invoice_line, = invoice.lines
>>> invoice_line.quantity
5.0
>>> stock_move, = invoice_line.stock_moves
>>> stock_move.quantity
5.0
>>> stock_move.state
'done'
Create a sale to be sent on invoice partially and check correctly linked to
invoices::
>>> sale = Sale()
>>> sale.party = customer
>>> sale.payment_term = payment_term
>>> sale.shipment_method = 'invoice'
>>> line = sale.lines.new()
>>> line.product = product
>>> line.quantity = 10.0
>>> sale.click('quote')
>>> sale.click('confirm')
>>> invoice, = sale.invoices
>>> invoice_line, = invoice.lines
>>> assertEqual(invoice_line.stock_moves, [])
>>> invoice_line.quantity = 5.0
>>> invoice.click('post')
>>> pay = invoice.click('pay')
>>> pay.form.payment_method = payment_method
>>> pay.execute('choice')
>>> invoice.reload()
>>> invoice.state
'paid'
>>> sale.reload()
>>> sale.invoice_state
'partially paid'
>>> invoice_line.reload()
>>> stock_move, = invoice_line.stock_moves
>>> stock_move.quantity
5.0
>>> stock_move.state
'draft'
Deleting a line from a invoice should recreate it::
>>> sale = Sale()
>>> sale.party = customer
>>> line = sale.lines.new()
>>> line.product = product
>>> line.quantity = 10.0
>>> sale.click('quote')
>>> sale.click('confirm')
>>> invoice, = sale.invoices
>>> invoice_line, = invoice.lines
>>> invoice.lines.remove(invoice_line)
>>> invoice.click('post')
>>> sale.reload()
>>> new_invoice, = sale.invoices
>>> new_invoice.number
>>> len(new_invoice.lines)
1

View File

@@ -0,0 +1,31 @@
=============================
Sale Default Methods Scenario
=============================
Imports::
>>> from proteus import Model
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('sale', create_company)
Create a party and set their default methods::
>>> Party = Model.get('party.party')
>>> customer = Party(name='Customer')
>>> customer.sale_shipment_method = 'invoice'
>>> customer.sale_invoice_method = 'shipment'
>>> customer.save()
Create a sale to to check default methods::
>>> Sale = Model.get('sale.sale')
>>> sale = Sale()
>>> sale.party = customer
>>> sale.shipment_method
'invoice'
>>> sale.invoice_method
'shipment'

View File

@@ -0,0 +1,59 @@
=======================
Sale with Default Taxes
=======================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_tax, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
>>> Party = Model.get('party.party')
>>> Sale = Model.get('sale.sale')
>>> Tax = Model.get('account.tax')
Get accounts::
>>> accounts = get_accounts()
Create tax::
>>> tax = create_tax(Decimal('.10'))
>>> tax.save()
>>> accounts['revenue'].taxes.append(Tax(tax.id))
>>> accounts['revenue'].save()
Create parties::
>>> customer = Party(name="Customer")
>>> customer.save()
Create a sale without product::
>>> sale = Sale(party=customer)
>>> line = sale.lines.new()
>>> assertEqual(line.taxes, [tax])
>>> line.quantity = 1
>>> line.unit_price = Decimal('100.0000')
>>> sale.click('quote')
>>> sale.total_amount
Decimal('110.00')
>>> sale.click('confirm')
>>> sale.state
'processing'
Check invoice::
>>> invoice, = sale.invoices
>>> invoice.total_amount
Decimal('110.00')
>>> line, = invoice.lines
>>> assertEqual(line.account, accounts['revenue'])

View File

@@ -0,0 +1,48 @@
===================
Sale Empty Scenario
===================
Imports::
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import create_chart
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
Create parties::
>>> Party = Model.get('party.party')
>>> customer = Party(name='Customer')
>>> customer.save()
Create empty sale::
>>> Sale = Model.get('sale.sale')
>>> sale = Sale()
>>> sale.party = customer
>>> sale.click('quote')
>>> sale.state
'quotation'
>>> sale.untaxed_amount
Decimal('0')
>>> sale.tax_amount
Decimal('0')
>>> sale.total_amount
Decimal('0')
>>> sale.click('confirm')
>>> sale.state
'done'
>>> sale.shipment_state
'none'
>>> len(sale.shipments)
0
>>> len(sale.shipment_returns)
0
>>> sale.invoice_state
'none'
>>> len(sale.invoices)
0

View File

@@ -0,0 +1,103 @@
============================
Sale Line Cancelled Scenario
============================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import create_chart, get_accounts
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
>>> Party = Model.get('party.party')
>>> ProductCategory = Model.get('product.category')
>>> ProductTemplate = Model.get('product.template')
>>> ProductUom = Model.get('product.uom')
>>> Sale = Model.get('sale.sale')
Get accounts::
>>> accounts = get_accounts()
Create party::
>>> customer = Party(name="Customer")
>>> customer.save()
Create product::
>>> account_category = ProductCategory(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_revenue = accounts['revenue']
>>> account_category.save()
>>> template = ProductTemplate(name="Product")
>>> template.default_uom, = ProductUom.find([('name', '=', "Unit")])
>>> template.type = 'goods'
>>> template.salable = True
>>> template.list_price = Decimal('10.0000')
>>> template.account_category = account_category
>>> template.save()
>>> product, = template.products
Sale product::
>>> sale = Sale(party=customer)
>>> line = sale.lines.new()
>>> line.product = product
>>> line.quantity = 1
>>> sale.click('quote')
>>> sale.click('confirm')
>>> sale.state
'processing'
>>> sale.shipment_state
'waiting'
>>> sale.invoice_state
'pending'
Cancel shipment and invoice::
>>> shipment, = sale.shipments
>>> shipment.click('cancel')
>>> shipment.state
'cancelled'
>>> invoice, = sale.invoices
>>> invoice.click('cancel')
>>> invoice.state
'cancelled'
>>> sale.reload()
>>> sale.state
'processing'
>>> sale.shipment_state
'exception'
>>> sale.invoice_state
'exception'
Ignore exceptions::
>>> invoice_handle_exception = sale.click('handle_invoice_exception')
>>> invoice_handle_exception.form.ignore_invoices.extend(
... invoice_handle_exception.form.ignore_invoices.find())
>>> invoice_handle_exception.execute('handle')
>>> sale.invoice_state
'none'
>>> shipment_handle_exception = sale.click('handle_shipment_exception')
>>> shipment_handle_exception.form.ignore_moves.extend(
... shipment_handle_exception.form.ignore_moves.find())
>>> shipment_handle_exception.execute('handle')
>>> sale.shipment_state
'none'
>>> sale.state
'done'

View File

@@ -0,0 +1,91 @@
=======================================
Sale Line Cancelled On Invoice Scenario
=======================================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import create_chart, get_accounts
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
>>> Party = Model.get('party.party')
>>> ProductCategory = Model.get('product.category')
>>> ProductTemplate = Model.get('product.template')
>>> ProductUom = Model.get('product.uom')
>>> Sale = Model.get('sale.sale')
Get accounts::
>>> accounts = get_accounts()
Create party::
>>> customer = Party(name="Customer")
>>> customer.save()
Create product::
>>> account_category = ProductCategory(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_revenue = accounts['revenue']
>>> account_category.save()
>>> template = ProductTemplate(name="Product")
>>> template.default_uom, = ProductUom.find([('name', '=', "Unit")])
>>> template.type = 'goods'
>>> template.salable = True
>>> template.list_price = Decimal('10.0000')
>>> template.account_category = account_category
>>> template.save()
>>> product, = template.products
Sale product::
>>> sale = Sale(party=customer)
>>> sale.shipment_method = 'invoice'
>>> line = sale.lines.new()
>>> line.product = product
>>> line.quantity = 1
>>> sale.click('quote')
>>> sale.click('confirm')
>>> sale.state
'processing'
>>> sale.shipment_state
'none'
>>> sale.invoice_state
'pending'
Cancel invoice::
>>> invoice, = sale.invoices
>>> invoice.click('cancel')
>>> invoice.state
'cancelled'
>>> sale.reload()
>>> sale.state
'processing'
>>> sale.shipment_state
'none'
>>> sale.invoice_state
'exception'
Ignore exception::
>>> invoice_handle_exception = sale.click('handle_invoice_exception')
>>> invoice_handle_exception.form.ignore_invoices.extend(
... invoice_handle_exception.form.ignore_invoices.find())
>>> invoice_handle_exception.execute('handle')
>>> sale.shipment_state
'none'
>>> sale.state
'done'

View File

@@ -0,0 +1,91 @@
========================================
Sale Line Cancelled On Shipment Scenario
========================================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import create_chart, get_accounts
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
>>> Party = Model.get('party.party')
>>> ProductCategory = Model.get('product.category')
>>> ProductTemplate = Model.get('product.template')
>>> ProductUom = Model.get('product.uom')
>>> Sale = Model.get('sale.sale')
Get accounts::
>>> accounts = get_accounts()
Create party::
>>> customer = Party(name="Customer")
>>> customer.save()
Create product::
>>> account_category = ProductCategory(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_revenue = accounts['revenue']
>>> account_category.save()
>>> template = ProductTemplate(name="Product")
>>> template.default_uom, = ProductUom.find([('name', '=', "Unit")])
>>> template.type = 'goods'
>>> template.salable = True
>>> template.list_price = Decimal('10.0000')
>>> template.account_category = account_category
>>> template.save()
>>> product, = template.products
Sale product::
>>> sale = Sale(party=customer)
>>> sale.invoice_method = 'shipment'
>>> line = sale.lines.new()
>>> line.product = product
>>> line.quantity = 1
>>> sale.click('quote')
>>> sale.click('confirm')
>>> sale.state
'processing'
>>> sale.shipment_state
'waiting'
>>> sale.invoice_state
'none'
Cancel shipment::
>>> shipment, = sale.shipments
>>> shipment.click('cancel')
>>> shipment.state
'cancelled'
>>> sale.reload()
>>> sale.state
'processing'
>>> sale.shipment_state
'exception'
>>> sale.invoice_state
'none'
Ignore exception::
>>> shipment_handle_exception = sale.click('handle_shipment_exception')
>>> shipment_handle_exception.form.ignore_moves.extend(
... shipment_handle_exception.form.ignore_moves.find())
>>> shipment_handle_exception.execute('handle')
>>> sale.shipment_state
'none'
>>> sale.state
'done'

View File

@@ -0,0 +1,90 @@
============================
Sale Manual Invoice Scenario
============================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import create_chart, get_accounts
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
>>> Party = Model.get('party.party')
>>> ProductCategory = Model.get('product.category')
>>> ProductTemplate = Model.get('product.template')
>>> ProductUom = Model.get('product.uom')
>>> Sale = Model.get('sale.sale')
Get accounts::
>>> accounts = get_accounts()
Create party::
>>> customer = Party(name="Customer")
>>> customer.save()
Create account category::
>>> account_category = ProductCategory(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_revenue = accounts['revenue']
>>> account_category.save()
Create product::
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'service'
>>> template.salable = True
>>> template.account_category = account_category
>>> template.list_price = Decimal('10')
>>> template.save()
>>> product, = template.products
Sale with manual invoice method::
>>> sale = Sale()
>>> sale.party = customer
>>> sale.invoice_method = 'manual'
>>> line = sale.lines.new()
>>> line.product = product
>>> line.quantity = 10
>>> sale.click('quote')
>>> sale.click('confirm')
>>> sale.state
'processing'
>>> sale.invoice_state
'none'
>>> len(sale.invoices)
0
Manually create an invoice::
>>> sale.click('manual_invoice')
>>> sale.state
'processing'
>>> sale.invoice_state
'pending'
Change quantity on invoice and create a new invoice::
>>> invoice, = sale.invoices
>>> line, = invoice.lines
>>> line.quantity = 5
>>> invoice.save()
>>> len(sale.invoices)
1
>>> sale.click('manual_invoice')
>>> len(sale.invoices)
2

View File

@@ -0,0 +1,76 @@
=============================
Sale Manual Shipment Scenario
=============================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules
Activate modules::
>>> config = activate_modules('sale', create_company)
>>> Party = Model.get('party.party')
>>> ProductCategory = Model.get('product.category')
>>> ProductTemplate = Model.get('product.template')
>>> ProductUom = Model.get('product.uom')
>>> Sale = Model.get('sale.sale')
Create party::
>>> customer = Party(name="Customer")
>>> customer.save()
Create product::
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> template = ProductTemplate()
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.salable = True
>>> template.list_price = Decimal('10')
>>> template.save()
>>> product, = template.products
Sale with manual shipment method::
>>> sale = Sale()
>>> sale.party = customer
>>> sale.shipment_method = 'manual'
>>> sale.invoice_method = 'manual' # no need for accounting
>>> line = sale.lines.new()
>>> line.product = product
>>> line.quantity = 10
>>> sale.click('quote')
>>> sale.click('confirm')
>>> sale.state
'processing'
>>> len(sale.shipments)
0
Manually create a shipment::
>>> sale.click('manual_shipment')
>>> sale.state
'processing'
>>> sale.shipment_state
'waiting'
Change quantity on shipment and create a new shipment::
>>> shipment, = sale.shipments
>>> move, = shipment.outgoing_moves
>>> move.quantity = 5
>>> shipment.save()
>>> len(sale.shipments)
1
>>> sale.click('manual_shipment')
>>> len(sale.shipments)
2

View File

@@ -0,0 +1,94 @@
===========================
Sale Modify Header Scenario
===========================
Imports::
>>> from decimal import Decimal
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_tax, get_accounts)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
Get accounts::
>>> accounts = get_accounts()
>>> revenue = accounts['revenue']
Create tax and tax rule::
>>> tax = create_tax(Decimal('.10'))
>>> tax.save()
>>> other_tax = create_tax(Decimal('.05'))
>>> other_tax.save()
>>> TaxRule = Model.get('account.tax.rule')
>>> foreign = TaxRule(name='Foreign Customers')
>>> foreign_tax = foreign.lines.new()
>>> foreign_tax.origin_tax = tax
>>> foreign_tax.tax = other_tax
>>> foreign.save()
Create account categories::
>>> ProductCategory = Model.get('product.category')
>>> account_category = ProductCategory(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_revenue = revenue
>>> account_category.customer_taxes.append(tax)
>>> account_category.save()
Create product::
>>> ProductUom = Model.get('product.uom')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> ProductTemplate = Model.get('product.template')
>>> template = ProductTemplate()
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.salable = True
>>> template.list_price = Decimal('10')
>>> template.account_category = account_category
>>> template.save()
>>> product, = template.products
Create parties::
>>> Party = Model.get('party.party')
>>> customer = Party(name='Customer')
>>> customer.save()
>>> another = Party(name='Another Customer', customer_tax_rule=foreign)
>>> another.save()
Create a sale with a line::
>>> Sale = Model.get('sale.sale')
>>> sale = Sale()
>>> sale.party = customer
>>> sale_line = sale.lines.new()
>>> sale_line.product = product
>>> sale_line.quantity = 3
>>> sale_line_comment = sale.lines.new(type='comment')
>>> sale.save()
>>> sale.untaxed_amount, sale.tax_amount, sale.total_amount
(Decimal('30.00'), Decimal('3.00'), Decimal('33.00'))
Change the party::
>>> modify_header = sale.click('modify_header')
>>> assertEqual(modify_header.form.party, customer)
>>> modify_header.form.party = another
>>> modify_header.execute('modify')
>>> sale.party.name
'Another Customer'
>>> sale.untaxed_amount, sale.tax_amount, sale.total_amount
(Decimal('30.00'), Decimal('1.50'), Decimal('31.50'))

View File

@@ -0,0 +1,57 @@
=======================
Sale Quotation Scenario
=======================
Imports::
>>> import datetime as dt
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import create_chart
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual
>>> today = dt.date.today()
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
>>> Cron = Model.get('ir.cron')
>>> Sale = Model.get('sale.sale')
>>> SaleConfiguration = Model.get('sale.configuration')
>>> Party = Model.get('party.party')
Set quotation validity to 1 week::
>>> sale_configuration = SaleConfiguration(1)
>>> sale_configuration.sale_quotation_validity = dt.timedelta(weeks=1)
>>> sale_configuration.save()
Create customer::
>>> customer = Party(name="Customer")
>>> customer.save()
Create a quotation::
>>> sale = Sale(party=customer)
>>> sale.click('quote')
>>> sale.state
'quotation'
>>> assertEqual(sale.quotation_date, today)
>>> assertEqual(sale.quotation_validity, dt.timedelta(weeks=1))
>>> assertEqual(sale.quotation_expire, today + dt.timedelta(weeks=1))
Expire quotation::
>>> sale.quotation_date = today - dt.timedelta(weeks=2)
>>> sale.save()
>>> cron, = Cron.find(
... [('method', '=', 'sale.sale|cancel_expired_quotation')], limit=1)
>>> cron.click('run_once')
>>> sale.reload()
>>> sale.state
'cancelled'

View File

@@ -0,0 +1,315 @@
=======================
Sale Reporting Scenario
=======================
Imports::
>>> from decimal import Decimal
>>> from dateutil.relativedelta import relativedelta
>>> from proteus import Model
>>> from trytond.modules.account.tests.tools import (
... create_chart, create_fiscalyear, get_accounts)
>>> from trytond.modules.account_invoice.tests.tools import (
... set_fiscalyear_invoice_sequences)
>>> from trytond.modules.company.tests.tools import create_company
>>> from trytond.tests.tools import activate_modules, assertEqual
Activate modules::
>>> config = activate_modules('sale', create_company, create_chart)
Create fiscal year::
>>> fiscalyear = set_fiscalyear_invoice_sequences(create_fiscalyear())
>>> fiscalyear.click('create_period')
Get accounts::
>>> accounts = get_accounts()
>>> revenue = accounts['revenue']
>>> expense = accounts['expense']
Create countries::
>>> Region = Model.get('country.region')
>>> Country = Model.get('country.country')
>>> Subdivision = Model.get('country.subdivision')
>>> north_america, = Region.find([('code_numeric', '=', '021')])
>>> country_us = Country(name="United States", region=north_america)
>>> country_us.save()
>>> california = Subdivision(
... name="California", type='state', country=country_us)
>>> california.save()
>>> new_york = Subdivision(
... name="New York", type='state', country=country_us)
>>> new_york.save()
Create party categories::
>>> PartyCategory = Model.get('party.category')
>>> party_category_root1 = PartyCategory(name="Root1")
>>> party_category_root1.save()
>>> party_category_child1 = PartyCategory(
... name="Child1", parent=party_category_root1)
>>> party_category_child1.save()
>>> party_category_child2 = PartyCategory(
... name="Child2", parent=party_category_root1)
>>> party_category_child2.save()
>>> party_category_root2 = PartyCategory(name="Root2")
>>> party_category_root2.save()
Create parties::
>>> Party = Model.get('party.party')
>>> customer1 = Party(name='Customer1')
>>> customer1.categories.append(PartyCategory(party_category_child1.id))
>>> customer1.categories.append(PartyCategory(party_category_root2.id))
>>> address, = customer1.addresses
>>> address.country = country_us
>>> address.subdivision = california
>>> customer1.save()
>>> customer2 = Party(name='Customer2')
>>> customer2.categories.append(PartyCategory(party_category_child2.id))
>>> address, = customer2.addresses
>>> address.country = country_us
>>> address.subdivision = new_york
>>> customer2.save()
Create account categories::
>>> Category = Model.get('product.category')
>>> account_category = Category(name="Account Category")
>>> account_category.accounting = True
>>> account_category.account_revenue = revenue
>>> account_category.save()
Create products::
>>> ProductUom = Model.get('product.uom')
>>> unit, = ProductUom.find([('name', '=', 'Unit')])
>>> ProductTemplate = Model.get('product.template')
>>> template1 = ProductTemplate()
>>> template1.name = "Product1"
>>> template1.default_uom = unit
>>> template1.type = 'service'
>>> template1.salable = True
>>> template1.list_price = Decimal('10')
>>> template1.account_category = account_category
>>> template1.save()
>>> product1, = template1.products
>>> template2, = template1.duplicate(default={'name': "Product2"})
>>> template2.account_category = account_category
>>> template2.save()
>>> product2, = template2.products
>>> category_root1 = Category(name="Root1")
>>> category_root1.save()
>>> category_child1 = Category(name="Child1", parent=category_root1)
>>> category_child1.save()
>>> category_child2 = Category(name="Child2", parent=category_root1)
>>> category_child2.save()
>>> category_root2 = Category(name="Root2")
>>> category_root2.save()
>>> template1.categories.append(Category(category_child1.id))
>>> template1.categories.append(Category(category_root2.id))
>>> template1.save()
>>> template2.categories.append(Category(category_child2.id))
>>> template2.save()
Create sales::
>>> Sale = Model.get('sale.sale')
>>> sale1 = Sale()
>>> sale1.party = customer1
>>> sale1.sale_date = fiscalyear.start_date
>>> line = sale1.lines.new()
>>> line.product = product1
>>> line.quantity = 2
>>> line = sale1.lines.new()
>>> line.product = product2
>>> line.quantity = 1
>>> sale1.click('quote')
>>> sale1.click('confirm')
>>> sale2 = Sale()
>>> sale2.party = customer2
>>> sale2.sale_date = fiscalyear.start_date + relativedelta(months=1)
>>> line = sale2.lines.new()
>>> line.product = product1
>>> line.quantity = 1
>>> sale2.click('quote')
>>> sale2.click('confirm')
Check sale reporting per customer::
>>> Customer = Model.get('sale.reporting.customer')
>>> CustomerTimeseries = Model.get('sale.reporting.customer.time_series')
>>> context = dict(
... from_date=fiscalyear.start_date,
... to_date=fiscalyear.end_date,
... period='month')
>>> with config.set_context(context=context):
... reports = Customer.find([])
... time_series = CustomerTimeseries.find([])
>>> len(reports)
2
>>> with config.set_context(context=context):
... assertEqual({(r.customer.id, r.number, r.revenue) for r in reports},
... {(customer1.id, 1, Decimal('30')),
... (customer2.id, 1, Decimal('10'))})
>>> len(time_series)
2
>>> with config.set_context(context=context):
... assertEqual({(r.customer.id, r.date, r.number, r.revenue)
... for r in time_series},
... {(customer1.id, sale1.sale_date.replace(day=1), 1, Decimal('30')),
... (customer2.id, sale2.sale_date.replace(day=1), 1, Decimal('10'))})
Check sale reporting per customer categories::
>>> CustomerCategory = Model.get('sale.reporting.customer.category')
>>> CustomerCategoryTimeseries = Model.get(
... 'sale.reporting.customer.category.time_series')
>>> CustomerCategoryTree = Model.get('sale.reporting.customer.category.tree')
>>> with config.set_context(context=context):
... reports = CustomerCategory.find([])
... time_series = CustomerCategoryTimeseries.find([])
... tree = CustomerCategoryTree.find([])
>>> len(reports)
3
>>> with config.set_context(context=context):
... assertEqual({(r.category.id, r.number, r.revenue) for r in reports},
... {(party_category_child1.id, 1, Decimal('30')),
... (party_category_root2.id, 1, Decimal('30')),
... (party_category_child2.id, 1, Decimal('10'))})
>>> len(time_series)
3
>>> with config.set_context(context=context):
... assertEqual({
... (r.category.id, r.date, r.number, r.revenue)
... for r in time_series},
... {
... (party_category_child1.id, sale1.sale_date.replace(day=1),
... 1, Decimal('30')),
... (party_category_root2.id, sale1.sale_date.replace(day=1),
... 1, Decimal('30')),
... (party_category_child2.id, sale2.sale_date.replace(day=1),
... 1, Decimal('10'))})
>>> len(tree)
4
>>> with config.set_context(context=context):
... assertEqual({(r.name, r.revenue) for r in tree},
... {('Root1', Decimal('40')),
... ('Child1', Decimal('30')),
... ('Child2', Decimal('10')),
... ('Root2', Decimal('30'))})
>>> child1, = CustomerCategoryTree.find([('rec_name', '=', 'Child1')])
>>> child1.rec_name
'Child1'
Check sale reporting per product::
>>> Product = Model.get('sale.reporting.product')
>>> ProductTimeseries = Model.get('sale.reporting.product.time_series')
>>> with config.set_context(context=context):
... reports = Product.find([])
... time_series = ProductTimeseries.find([])
>>> len(reports)
2
>>> with config.set_context(context=context):
... assertEqual({(r.product.id, r.number, r.revenue) for r in reports},
... {(product1.id, 2, Decimal('30')),
... (product2.id, 1, Decimal('10'))})
>>> len(time_series)
3
>>> with config.set_context(context=context):
... assertEqual({(r.product.id, r.date, r.number, r.revenue)
... for r in time_series},
... {(product1.id, sale1.sale_date.replace(day=1), 1, Decimal('20')),
... (product2.id, sale1.sale_date.replace(day=1), 1, Decimal('10')),
... (product1.id, sale2.sale_date.replace(day=1), 1, Decimal('10'))})
Check sale reporting per product categories::
>>> ProductCategory = Model.get('sale.reporting.product.category')
>>> ProductCategoryTimeseries = Model.get(
... 'sale.reporting.product.category.time_series')
>>> ProductCategoryTree = Model.get('sale.reporting.product.category.tree')
>>> with config.set_context(context=context):
... reports = ProductCategory.find([])
... time_series = ProductCategoryTimeseries.find([])
... tree = ProductCategoryTree.find([])
>>> len(reports)
4
>>> with config.set_context(context=context):
... assertEqual({(r.category.id, r.number, r.revenue) for r in reports},
... {(category_child1.id, 2, Decimal('30')),
... (category_root2.id, 2, Decimal('30')),
... (category_child2.id, 1, Decimal('10')),
... (account_category.id, 2, Decimal('40'))})
>>> len(time_series)
7
>>> with config.set_context(context=context):
... assertEqual({(r.category.id, r.date, r.number, r.revenue)
... for r in time_series},
... {(category_child1.id, sale1.sale_date.replace(day=1), 1, Decimal('20')),
... (category_root2.id, sale1.sale_date.replace(day=1), 1, Decimal('20')),
... (category_child2.id, sale1.sale_date.replace(day=1), 1, Decimal('10')),
... (category_child1.id, sale2.sale_date.replace(day=1), 1, Decimal('10')),
... (category_root2.id, sale2.sale_date.replace(day=1), 1, Decimal('10')),
... (account_category.id, sale1.sale_date.replace(day=1), 1, Decimal('30')),
... (account_category.id, sale2.sale_date.replace(day=1), 1, Decimal('10'))})
>>> len(tree)
5
>>> with config.set_context(context=context):
... assertEqual({(r.name, r.revenue) for r in tree},
... {('Root1', Decimal('40')),
... ('Child1', Decimal('30')),
... ('Child2', Decimal('10')),
... ('Root2', Decimal('30')),
... ('Account Category', Decimal('40'))})
>>> child1, = ProductCategoryTree.find([('rec_name', '=', 'Child1')])
>>> child1.rec_name
'Child1'
Check sale reporting per countries::
>>> RegionTree = Model.get('sale.reporting.region.tree')
>>> CountryTree = Model.get('sale.reporting.country.tree')
>>> CountryTimeseries = Model.get('sale.reporting.country.time_series')
>>> SubdivisionTimeseries = Model.get(
... 'sale.reporting.country.subdivision.time_series')
>>> with config.set_context(context=context):
... region = RegionTree(north_america.id)
... countries = CountryTree.find([])
... country_time_series = CountryTimeseries.find([])
... subdivision_time_series = SubdivisionTimeseries.find([])
>>> region.revenue
Decimal('40.00')
>>> region.parent.revenue
Decimal('40.00')
>>> len(countries)
3
>>> with config.set_context(context=context):
... sorted((c.region, c.number, c.revenue) for c in countries)
[('California', 1, Decimal('30.00')), ('New York', 1, Decimal('10.00')), ('United States', 2, Decimal('40.00'))]
>>> len(country_time_series)
2
>>> with config.set_context(context=context):
... assertEqual({(r.country.id, r.date, r.number, r.revenue)
... for r in country_time_series},
... {(country_us.id, sale1.sale_date.replace(day=1), 1, Decimal('30')),
... (country_us.id, sale2.sale_date.replace(day=1), 1, Decimal('10'))})
>>> len(subdivision_time_series)
2
>>> with config.set_context(context=context):
... assertEqual({(r.subdivision.id, r.date, r.number, r.revenue)
... for r in subdivision_time_series},
... {(california.id, sale1.sale_date.replace(day=1), 1, Decimal('30')),
... (new_york.id, sale2.sale_date.replace(day=1), 1, Decimal('10'))})

View File

@@ -0,0 +1,71 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from decimal import Decimal
from trytond.modules.account.tests import create_chart
from trytond.modules.company.tests import (
CompanyTestMixin, PartyCompanyCheckEraseMixin, create_company, set_company)
from trytond.modules.party.tests import PartyCheckReplaceMixin
from trytond.pool import Pool
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
from trytond.transaction import Transaction
class SaleTestCase(
PartyCompanyCheckEraseMixin, PartyCheckReplaceMixin, CompanyTestMixin,
ModuleTestCase):
'Test Sale module'
module = 'sale'
@with_transaction()
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([
('closed', '!=', True),
('type.receivable', '=', True),
('party_required', '=', True),
('company', '=', company.id),
], limit=1)
payable, = Account.search([
('closed', '!=', True),
('type.payable', '=', True),
('party_required', '=', True),
('company', '=', company.id),
], limit=1)
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.9618')})
prices = Product.get_sale_price([product], quantity=1.5)
self.assertEqual(prices, {product.id: Decimal('2267.9618')})
del ModuleTestCase

View File

@@ -0,0 +1,8 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
from trytond.tests.test_tryton import load_doc_tests
def load_tests(*args, **kwargs):
return load_doc_tests(__name__, __file__, *args, **kwargs)