It set the context on the products selection so the user can see the quantity that will be set. As it is possible to search on this quantity, there is no more the need to prefill the selection with products having a quantity. Also there is no need to have two steps for the wizard as the context is computed dynamically.
351 lines
14 KiB
Python
351 lines
14 KiB
Python
# This file is part of Tryton. The COPYRIGHT file at the top level of
|
|
# this repository contains the full copyright notices and license terms.
|
|
|
|
import datetime
|
|
from decimal import Decimal
|
|
|
|
from dateutil.relativedelta import relativedelta
|
|
|
|
from trytond.modules.company.tests import (
|
|
CompanyTestMixin, create_company, set_company)
|
|
from trytond.pool import Pool
|
|
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
|
|
from trytond.transaction import Transaction
|
|
|
|
|
|
class StockForecastTestCase(CompanyTestMixin, ModuleTestCase):
|
|
'Test StockForecast module'
|
|
module = 'stock_forecast'
|
|
|
|
@with_transaction()
|
|
def test_forecast_rec_name(self):
|
|
pool = Pool()
|
|
Forecast = pool.get('stock.forecast')
|
|
Location = pool.get('stock.location')
|
|
|
|
customer, = Location.search([('code', '=', 'CUS')])
|
|
warehouse, = Location.search([('code', '=', 'WH')])
|
|
storage, = Location.search([('code', '=', 'STO')])
|
|
company = create_company()
|
|
with set_company(company):
|
|
forecast = Forecast(
|
|
warehouse=warehouse,
|
|
destination=customer,
|
|
from_date=datetime.date(2023, 1, 1),
|
|
to_date=datetime.date(2023, 3, 31),
|
|
)
|
|
forecast.save()
|
|
forecasts = Forecast.search([('rec_name', '=', "Warehouse")])
|
|
|
|
self.assertEqual(
|
|
forecast.rec_name,
|
|
"Warehouse → Customer @ [01/01/2023 - 03/31/2023]")
|
|
self.assertEqual(forecasts, [forecast])
|
|
|
|
@with_transaction()
|
|
def test_distribute(self):
|
|
'Test distribute'
|
|
pool = Pool()
|
|
Line = pool.get('stock.forecast.line')
|
|
line = Line()
|
|
for values, result in (
|
|
((1, 5), {0: 5}),
|
|
((4, 8), {0: 2, 1: 2, 2: 2, 3: 2}),
|
|
((2, 5), {0: 2, 1: 3}),
|
|
((10, 4), {0: 0, 1: 1, 2: 0, 3: 1, 4: 0,
|
|
5: 0, 6: 1, 7: 0, 8: 1, 9: 0}),
|
|
):
|
|
self.assertEqual(line.distribute(*values), result)
|
|
|
|
@with_transaction()
|
|
def test_create_moves_before(self):
|
|
"Test create moves before start date"
|
|
pool = Pool()
|
|
Uom = pool.get('product.uom')
|
|
Template = pool.get('product.template')
|
|
Product = pool.get('product.product')
|
|
Location = pool.get('stock.location')
|
|
Forecast = pool.get('stock.forecast')
|
|
Move = pool.get('stock.move')
|
|
|
|
unit, = Uom.search([('name', '=', 'Unit')])
|
|
template, = Template.create([{
|
|
'name': 'Test create_moves',
|
|
'type': 'goods',
|
|
'default_uom': unit.id,
|
|
}])
|
|
product, = Product.create([{
|
|
'template': template.id,
|
|
}])
|
|
customer, = Location.search([('code', '=', 'CUS')])
|
|
warehouse, = Location.search([('code', '=', 'WH')])
|
|
storage, = Location.search([('code', '=', 'STO')])
|
|
company = create_company()
|
|
with set_company(company):
|
|
today = datetime.date.today()
|
|
|
|
forecast, = Forecast.create([{
|
|
'warehouse': warehouse.id,
|
|
'destination': customer.id,
|
|
'from_date': today + relativedelta(months=1, day=1),
|
|
'to_date': today + relativedelta(months=1, day=20),
|
|
'company': company.id,
|
|
'lines': [
|
|
('create', [{
|
|
'product': product.id,
|
|
'quantity': 10,
|
|
'uom': unit.id,
|
|
'minimal_quantity': 2,
|
|
}],
|
|
),
|
|
],
|
|
}])
|
|
Forecast.confirm([forecast])
|
|
|
|
Forecast.create_moves([forecast])
|
|
line, = forecast.lines
|
|
self.assertEqual(line.quantity_executed, 0)
|
|
self.assertEqual(len(line.moves), 5)
|
|
self.assertEqual(sum(move.quantity for move in line.moves), 10)
|
|
self.assertGreaterEqual(
|
|
min(m.planned_date for m in line.moves), forecast.from_date)
|
|
|
|
Forecast.delete_moves([forecast])
|
|
line, = forecast.lines
|
|
self.assertEqual(len(line.moves), 0)
|
|
|
|
Move.create([{
|
|
'from_location': storage.id,
|
|
'to_location': customer.id,
|
|
'product': product.id,
|
|
'uom': unit.id,
|
|
'quantity': 2,
|
|
'planned_date': today + relativedelta(months=1, day=5),
|
|
'company': company.id,
|
|
'currency': company.currency.id,
|
|
'unit_price': Decimal('1'),
|
|
}])
|
|
line, = forecast.lines
|
|
self.assertEqual(line.quantity_executed, 2)
|
|
|
|
Forecast.create_moves([forecast])
|
|
line, = forecast.lines
|
|
self.assertEqual(line.quantity_executed, 2)
|
|
self.assertEqual(len(line.moves), 4)
|
|
self.assertEqual(sum(move.quantity for move in line.moves), 8)
|
|
self.assertGreaterEqual(
|
|
min(m.planned_date for m in line.moves), forecast.from_date)
|
|
|
|
@with_transaction()
|
|
def test_create_moves_during(self):
|
|
"Test create moves during the period"
|
|
pool = Pool()
|
|
Uom = pool.get('product.uom')
|
|
Template = pool.get('product.template')
|
|
Product = pool.get('product.product')
|
|
Location = pool.get('stock.location')
|
|
Forecast = pool.get('stock.forecast')
|
|
Move = pool.get('stock.move')
|
|
|
|
unit, = Uom.search([('name', '=', 'Unit')])
|
|
template, = Template.create([{
|
|
'name': 'Test create_moves',
|
|
'type': 'goods',
|
|
'default_uom': unit.id,
|
|
}])
|
|
product, = Product.create([{
|
|
'template': template.id,
|
|
}])
|
|
customer, = Location.search([('code', '=', 'CUS')])
|
|
warehouse, = Location.search([('code', '=', 'WH')])
|
|
storage, = Location.search([('code', '=', 'STO')])
|
|
company = create_company()
|
|
with set_company(company):
|
|
today = datetime.date.today()
|
|
|
|
forecast, = Forecast.create([{
|
|
'warehouse': warehouse.id,
|
|
'destination': customer.id,
|
|
'from_date': today - relativedelta(days=20),
|
|
'to_date': today + relativedelta(days=10),
|
|
'company': company.id,
|
|
'lines': [
|
|
('create', [{
|
|
'product': product.id,
|
|
'quantity': 20,
|
|
'uom': unit.id,
|
|
'minimal_quantity': 2,
|
|
}],
|
|
),
|
|
],
|
|
}])
|
|
Forecast.confirm([forecast])
|
|
|
|
Forecast.create_moves([forecast])
|
|
line, = forecast.lines
|
|
self.assertEqual(line.quantity_executed, 0)
|
|
self.assertEqual(len(line.moves), 10)
|
|
self.assertEqual(sum(move.quantity for move in line.moves), 20)
|
|
self.assertGreaterEqual(
|
|
min(m.planned_date for m in line.moves), today)
|
|
|
|
Forecast.delete_moves([forecast])
|
|
line, = forecast.lines
|
|
self.assertEqual(len(line.moves), 0)
|
|
|
|
Move.create([{
|
|
'from_location': storage.id,
|
|
'to_location': customer.id,
|
|
'product': product.id,
|
|
'uom': unit.id,
|
|
'quantity': 10,
|
|
'planned_date': today - relativedelta(days=5),
|
|
'company': company.id,
|
|
'currency': company.currency.id,
|
|
'unit_price': Decimal('1'),
|
|
}])
|
|
line, = forecast.lines
|
|
self.assertEqual(line.quantity_executed, 10)
|
|
|
|
Forecast.create_moves([forecast])
|
|
line, = forecast.lines
|
|
self.assertEqual(line.quantity_executed, 10)
|
|
self.assertEqual(len(line.moves), 5)
|
|
self.assertEqual(sum(move.quantity for move in line.moves), 10)
|
|
self.assertGreaterEqual(
|
|
min(m.planned_date for m in line.moves), today)
|
|
|
|
@with_transaction()
|
|
def test_create_moves_after(self):
|
|
"Test create not moves after end date"
|
|
pool = Pool()
|
|
Uom = pool.get('product.uom')
|
|
Template = pool.get('product.template')
|
|
Product = pool.get('product.product')
|
|
Location = pool.get('stock.location')
|
|
Forecast = pool.get('stock.forecast')
|
|
|
|
unit, = Uom.search([('name', '=', 'Unit')])
|
|
template, = Template.create([{
|
|
'name': 'Test create_moves',
|
|
'type': 'goods',
|
|
'default_uom': unit.id,
|
|
}])
|
|
product, = Product.create([{
|
|
'template': template.id,
|
|
}])
|
|
customer, = Location.search([('code', '=', 'CUS')])
|
|
warehouse, = Location.search([('code', '=', 'WH')])
|
|
storage, = Location.search([('code', '=', 'STO')])
|
|
company = create_company()
|
|
with set_company(company):
|
|
today = datetime.date.today()
|
|
|
|
forecast, = Forecast.create([{
|
|
'warehouse': warehouse.id,
|
|
'destination': customer.id,
|
|
'from_date': today - relativedelta(days=20),
|
|
'to_date': today - relativedelta(days=10),
|
|
'company': company.id,
|
|
'lines': [
|
|
('create', [{
|
|
'product': product.id,
|
|
'quantity': 20,
|
|
'uom': unit.id,
|
|
'minimal_quantity': 2,
|
|
}],
|
|
),
|
|
],
|
|
}])
|
|
Forecast.confirm([forecast])
|
|
|
|
Forecast.create_moves([forecast])
|
|
line, = forecast.lines
|
|
self.assertEqual(len(line.moves), 0)
|
|
|
|
@with_transaction()
|
|
def test_complete(self):
|
|
'Test complete'
|
|
pool = Pool()
|
|
Uom = pool.get('product.uom')
|
|
Template = pool.get('product.template')
|
|
Product = pool.get('product.product')
|
|
Location = pool.get('stock.location')
|
|
Forecast = pool.get('stock.forecast')
|
|
Move = pool.get('stock.move')
|
|
ForecastComplete = pool.get('stock.forecast.complete', type='wizard')
|
|
|
|
unit, = Uom.search([('name', '=', 'Unit')])
|
|
template, = Template.create([{
|
|
'name': 'Test complete',
|
|
'type': 'goods',
|
|
'default_uom': unit.id,
|
|
}])
|
|
product, = Product.create([{
|
|
'template': template.id,
|
|
}])
|
|
customer, = Location.search([('code', '=', 'CUS')])
|
|
supplier, = Location.search([('code', '=', 'SUP')])
|
|
warehouse, = Location.search([('code', '=', 'WH')])
|
|
storage, = Location.search([('code', '=', 'STO')])
|
|
company = create_company()
|
|
with set_company(company):
|
|
today = datetime.date.today()
|
|
|
|
moves = Move.create([{
|
|
'from_location': supplier.id,
|
|
'to_location': storage.id,
|
|
'product': product.id,
|
|
'uom': unit.id,
|
|
'quantity': 10,
|
|
'effective_date': (today
|
|
+ relativedelta(months=-1, day=1)),
|
|
'company': company.id,
|
|
'currency': company.currency.id,
|
|
'unit_price': Decimal('1'),
|
|
}, {
|
|
'from_location': storage.id,
|
|
'to_location': customer.id,
|
|
'product': product.id,
|
|
'uom': unit.id,
|
|
'quantity': 5,
|
|
'effective_date': (today
|
|
+ relativedelta(months=-1, day=15)),
|
|
'company': company.id,
|
|
'currency': company.currency.id,
|
|
'unit_price': Decimal('1'),
|
|
}])
|
|
Move.do(moves)
|
|
|
|
forecast, = Forecast.create([{
|
|
'warehouse': warehouse.id,
|
|
'destination': customer.id,
|
|
'from_date': today + relativedelta(months=1, day=1),
|
|
'to_date': today + relativedelta(months=1, day=20),
|
|
'company': company.id,
|
|
}])
|
|
|
|
with Transaction().set_context(
|
|
active_model=Forecast.__name__, active_id=forecast.id):
|
|
session_id, _, _ = ForecastComplete.create()
|
|
forecast_complete = ForecastComplete(session_id)
|
|
forecast_complete.ask.company = company
|
|
forecast_complete.ask.warehouse = warehouse
|
|
forecast_complete.ask.destination = customer
|
|
forecast_complete.ask.from_date = (
|
|
today + relativedelta(months=-1, day=1))
|
|
forecast_complete.ask.to_date = (
|
|
today + relativedelta(months=-1, day=20))
|
|
forecast_complete.ask.products = [product]
|
|
forecast_complete.transition_complete()
|
|
|
|
self.assertEqual(len(forecast.lines), 1)
|
|
forecast_line, = forecast.lines
|
|
self.assertEqual(forecast_line.product, product)
|
|
self.assertEqual(forecast_line.uom, unit)
|
|
self.assertEqual(forecast_line.quantity, 5)
|
|
self.assertEqual(forecast_line.minimal_quantity, 1)
|
|
|
|
|
|
del ModuleTestCase
|