Update to 4.7

This commit is contained in:
C?dric Krier 2018-03-19 16:59:17 +01:00
parent b35d4335cf
commit 279d397b5f
9 changed files with 178 additions and 91 deletions

57
.drone.yml Normal file
View File

@ -0,0 +1,57 @@
clone:
hg:
image: plugins/hg
pipeline:
tox:
image: ${IMAGE}
environment:
- CFLAGS=-O0
- DB_CACHE=/cache
- TOX_TESTENV_PASSENV=CFLAGS DB_CACHE
- POSTGRESQL_URI=postgresql://postgres@postgresql:5432/
commands:
- pip install tox
- tox -e "${TOXENV}-${DATABASE}"
notify:
image: drillster/drone-email
from: drone@localhost
host: smtp
port: 25
skip_verify: true
when:
status: [ changed, failure ]
services:
postgresql:
image: postgres
when:
matrix:
DATABASE: postgresql
matrix:
include:
- IMAGE: python:2.7
TOXENV: py27
DATABASE: sqlite
- IMAGE: python:2.7
TOXENV: py27
DATABASE: postgresql
- IMAGE: python:3.4
TOXENV: py34
DATABASE: sqlite
- IMAGE: python:3.4
TOXENV: py34
DATABASE: postgresql
- IMAGE: python:3.5
TOXENV: py35
DATABASE: sqlite
- IMAGE: python:3.5
TOXENV: py35
DATABASE: postgresql
- IMAGE: python:3.6
TOXENV: py36
DATABASE: sqlite
- IMAGE: python:3.6
TOXENV: py36
DATABASE: postgresql

View File

@ -1,13 +1,13 @@
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from trytond.pool import Pool
from .production import *
from . import production
def register():
Pool.register(
Configuration,
ConfigurationCompany,
Production,
StockMove,
production.Configuration,
production.ConfigurationCompany,
production.Production,
production.StockMove,
module='production_output_lot', type_='model')

View File

@ -1,12 +1,11 @@
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from trytond.model import Model, ModelSQL, fields
from trytond.model import ModelSQL, fields
from trytond.pool import Pool, PoolMeta
from trytond.pyson import Eval
from trytond.transaction import Transaction
from trytond.modules.company.model import CompanyValueMixin
__all__ = ['Configuration', 'ConfigurationCompany', 'Production', 'StockMove']
__metaclass__ = PoolMeta
_OUTPUT_LOT_CREATION = [
('running', 'Production in Running'),
@ -15,71 +14,38 @@ _OUTPUT_LOT_CREATION = [
class Configuration:
__metaclass__ = PoolMeta
__name__ = 'production.configuration'
output_lot_creation = fields.Function(fields.Selection(
output_lot_creation = fields.MultiValue(fields.Selection(
_OUTPUT_LOT_CREATION, 'When Output Lot is created?', required=True,
help='The Production\'s state in which the Output Lot will be '
'created automatically, if the Output Product is configured to '
'require lot in production.'),
'get_company_config', setter='set_company_config')
output_lot_sequence = fields.Function(fields.Many2One('ir.sequence',
'require lot in production.'))
output_lot_sequence = fields.MultiValue(fields.Many2One('ir.sequence',
'Output Lot Sequence', required=True, domain=[
('company', 'in',
[Eval('context', {}).get('company', -1), None]),
('code', '=', 'stock.lot'),
]),
'get_company_config', setter='set_company_config')
@staticmethod
def default_output_lot_creation():
return 'running'
]))
@classmethod
def get_company_config(cls, configs, names):
def multivalue_model(cls, field):
pool = Pool()
CompanyConfig = pool.get('production.configuration.company')
company_id = Transaction().context.get('company')
company_configs = CompanyConfig.search([
('company', '=', company_id),
])
res = {}
for fname in names:
res[fname] = {
configs[0].id: None,
}
if company_configs:
val = getattr(company_configs[0], fname)
if isinstance(val, Model):
val = val.id
res[fname][configs[0].id] = val
return res
if field in {'output_lot_creation', 'output_lot_sequence'}:
return pool.get('production.configuration.company')
return super(Configuration, cls).multivalue_model(field)
@classmethod
def set_company_config(cls, configs, name, value):
pool = Pool()
CompanyConfig = pool.get('production.configuration.company')
company_id = Transaction().context.get('company')
company_configs = CompanyConfig.search([
('company', '=', company_id),
])
if company_configs:
company_config = company_configs[0]
else:
company_config = CompanyConfig(company=company_id)
setattr(company_config, name, value)
company_config.save()
def default_output_lot_creation(cls, **pattern):
return cls.multivalue_model(
'output_lot_creation').default_output_lot_creation()
class ConfigurationCompany(ModelSQL):
class ConfigurationCompany(ModelSQL, CompanyValueMixin):
'Production Configuration by Company'
__name__ = 'production.configuration.company'
company = fields.Many2One('company.company', 'Company', required=True,
ondelete='CASCADE', select=True)
output_lot_creation = fields.Selection([(None, '')] + _OUTPUT_LOT_CREATION,
'When Output Lot is created?')
output_lot_sequence = fields.Many2One('ir.sequence',
@ -88,8 +54,13 @@ class ConfigurationCompany(ModelSQL):
('code', '=', 'stock.lot'),
], depends=['company'])
@classmethod
def default_output_lot_creation(cls):
return 'running'
class Production:
__metaclass__ = PoolMeta
__name__ = 'production'
@classmethod
@ -149,6 +120,7 @@ class Production:
class StockMove:
__metaclass__ = PoolMeta
__name__ = 'stock.move'
@classmethod

View File

@ -4,7 +4,11 @@
from setuptools import setup
import re
import os
import ConfigParser
import io
try:
from configparser import ConfigParser
except ImportError:
from ConfigParser import ConfigParser
MODULE = 'production_output_lot'
PREFIX = 'nantic'
@ -12,30 +16,57 @@ MODULE2PREFIX = {}
def read(fname):
return open(os.path.join(os.path.dirname(__file__), fname)).read()
return io.open(
os.path.join(os.path.dirname(__file__), fname),
'r', encoding='utf-8').read()
config = ConfigParser.ConfigParser()
def get_require_version(name):
if minor_version % 2:
require = '%s >= %s.%s.dev0, < %s.%s'
else:
require = '%s >= %s.%s, < %s.%s'
require %= (name, major_version, minor_version,
major_version, minor_version + 1)
return require
config = ConfigParser()
config.readfp(open('tryton.cfg'))
info = dict(config.items('tryton'))
for key in ('depends', 'extras_depend', 'xml'):
if key in info:
info[key] = info[key].strip().splitlines()
major_version, minor_version, _ = info.get('version', '0.0.1').split('.', 2)
version = info.get('version', '0.0.1')
major_version, minor_version, _ = version.split('.', 2)
major_version = int(major_version)
minor_version = int(minor_version)
requires = []
for dep in info.get('depends', []):
if not re.match(r'(ir|res|webdav)(\W|$)', dep):
if not re.match(r'(ir|res)(\W|$)', dep):
prefix = MODULE2PREFIX.get(dep, 'trytond')
requires.append('%s_%s >= %s.%s, < %s.%s' %
(prefix, dep, major_version, minor_version,
major_version, minor_version + 1))
requires.append('trytond >= %s.%s, < %s.%s' %
(major_version, minor_version, major_version, minor_version + 1))
requires.append(get_require_version('%s_%s' % (prefix, dep)))
requires.append(get_require_version('trytond'))
tests_require = ['proteus >= %s.%s, < %s.%s' %
(major_version, minor_version, major_version, minor_version + 1)]
tests_require = [get_require_version('proteus'),
get_require_version('nantic_stock_lot_sequence')]
series = '%s.%s' % (major_version, minor_version)
if minor_version % 2:
branch = 'default'
else:
branch = series
dependency_links = [
('hg+https://bitbucket.org/nantic/'
'trytond-stock_lot_sequence@%(branch)s'
'#egg=nantic-stock_lot_sequence-%(series)s' % {
'branch': branch,
'series': series,
}),
]
if minor_version % 2:
# Add development index for testing with proteus
dependency_links.append('https://trydevpi.tryton.org/')
setup(name='%s_%s' % (PREFIX, MODULE),
version=info.get('version', '0.0.1'),
@ -51,7 +82,7 @@ setup(name='%s_%s' % (PREFIX, MODULE),
],
package_data={
'trytond.modules.%s' % MODULE: (info.get('xml', [])
+ ['tryton.cfg', 'locale/*.po', 'tests/*.rst']),
+ ['tryton.cfg', 'view/*.xml', 'locale/*.po', 'tests/*.rst']),
},
classifiers=[
'Development Status :: 5 - Production/Stable',
@ -71,12 +102,17 @@ setup(name='%s_%s' % (PREFIX, MODULE),
'Natural Language :: Russian',
'Natural Language :: Spanish',
'Operating System :: OS Independent',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Office/Business',
],
license='GPL-3',
install_requires=requires,
dependency_links=dependency_links,
zip_safe=False,
entry_points="""
[trytond.modules]
@ -85,4 +121,8 @@ setup(name='%s_%s' % (PREFIX, MODULE),
test_suite='tests',
test_loader='trytond.test_loader:Loader',
tests_require=tests_require,
use_2to3=True,
convert_2to3_doctests=[
'tests/scenario_production_lot_sequence.rst',
],
)

View File

@ -1,3 +1,8 @@
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from .test_production_output_lot import suite
try:
from trytond.modules.production_output_lot.tests.test_production_output_lot import suite
except ImportError:
from .test_production_output_lot import suite
__all__ = ['suite']

View File

@ -8,23 +8,15 @@ Imports::
>>> from dateutil.relativedelta import relativedelta
>>> from decimal import Decimal
>>> from proteus import config, Model, Wizard
>>> from trytond.tests.tools import activate_modules
>>> from trytond.modules.company.tests.tools import create_company, \
... get_company
>>> today = datetime.date.today()
>>> yesterday = today - relativedelta(days=1)
Create database::
>>> config = config.set_trytond()
>>> config.pool.test = True
Install production_output_lot Module::
>>> Module = Model.get('ir.module')
>>> modules = Module.find([
... ('name', 'in', ['production_output_lot', 'stock_lot_sequence'])])
>>> Module.install([x.id for x in modules], config.context)
>>> Wizard('ir.module.install_upgrade').execute('upgrade')
>>> config = activate_modules(['production_output_lot', 'stock_lot_sequence'])
Create company::
@ -43,12 +35,13 @@ Create product::
>>> template.name = 'product'
>>> template.default_uom = unit
>>> template.type = 'goods'
>>> template.producible = True
>>> template.list_price = Decimal(30)
>>> template.cost_price = Decimal(20)
>>> template.serial_number = True
>>> template.lot_required.extend(LotType.find([]))
>>> template.save()
>>> product.template = template
>>> product.cost_price = Decimal(20)
>>> product.save()
Create Components::
@ -59,9 +52,9 @@ Create Components::
>>> template1.default_uom = unit
>>> template1.type = 'goods'
>>> template1.list_price = Decimal(5)
>>> template1.cost_price = Decimal(1)
>>> template1.save()
>>> component1.template = template1
>>> component1.cost_price = Decimal(1)
>>> component1.save()
>>> meter, = ProductUom.find([('name', '=', 'Meter')])
@ -72,9 +65,9 @@ Create Components::
>>> template2.default_uom = meter
>>> template2.type = 'goods'
>>> template2.list_price = Decimal(7)
>>> template2.cost_price = Decimal(5)
>>> template2.save()
>>> component2.template = template2
>>> component2.cost_price = Decimal(5)
>>> component2.save()
Create Bill of Material::
@ -155,7 +148,7 @@ Make a production::
u'1'
>>> output_sequence.reload()
>>> output_sequence.number_next
2L
2
Make a production which uses the lot from product::
@ -181,7 +174,7 @@ Make a production which uses the lot from product::
u'1'
>>> output_sequence.reload()
>>> output_sequence.number_next
2L
2
>>> product_sequence.reload()
>>> product_sequence.number_next
2L
2

View File

@ -8,7 +8,7 @@ import trytond.tests.test_tryton
from trytond.exceptions import UserError
from trytond.pool import Pool
from trytond.tests.test_tryton import ModuleTestCase, with_transaction
from trytond.tests.test_tryton import doctest_setup, doctest_teardown
from trytond.tests.test_tryton import doctest_teardown
from trytond.tests.test_tryton import doctest_checker
from trytond.modules.company.tests import create_company, set_company
@ -68,31 +68,33 @@ class TestCase(ModuleTestCase):
'type': 'goods',
'consumable': True,
'list_price': Decimal(10),
'cost_price': Decimal(5),
'cost_price_method': 'fixed',
'default_uom': kg.id,
}, {
'name': 'Output Product without Lot',
'type': 'goods',
'producible': True,
'list_price': Decimal(20),
'cost_price': Decimal(10),
'cost_price_method': 'fixed',
'default_uom': kg.id,
}, {
'name': 'Output Product with Lot',
'type': 'goods',
'producible': True,
'list_price': Decimal(20),
'cost_price': Decimal(10),
'cost_price_method': 'fixed',
'default_uom': kg.id,
}])
(input_product, output_product_wo_lot,
output_product_w_lot) = Product.create([{
'template': input_template.id,
'cost_price': Decimal(5),
}, {
'template': output_template_wo_lot.id,
'cost_price': Decimal(10),
}, {
'template': output_template_w_lot.id,
'cost_price': Decimal(10),
}])
lot_types = LotType.search([])
Template_lot_type.create([{
@ -204,7 +206,7 @@ def suite():
suite = trytond.tests.test_tryton.suite()
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCase))
suite.addTests(doctest.DocFileSuite('scenario_production_lot_sequence.rst',
setUp=doctest_setup, tearDown=doctest_teardown, encoding='utf-8',
tearDown=doctest_teardown, encoding='utf-8',
checker=doctest_checker,
optionflags=doctest.REPORT_ONLY_FIRST_FAILURE))
return suite

18
tox.ini Normal file
View File

@ -0,0 +1,18 @@
[tox]
envlist = {py27,py34,py35,py36}-{sqlite,postgresql,mysql},pypy-{sqlite,postgresql}
[testenv]
commands = {envpython} setup.py test
deps =
{py27,py34,py35,py36}-postgresql: psycopg2 >= 2.5
pypy-postgresql: psycopg2cffi >= 2.5
mysql: MySQL-python
sqlite: sqlitebck
setenv =
sqlite: TRYTOND_DATABASE_URI={env:SQLITE_URI:sqlite://}
postgresql: TRYTOND_DATABASE_URI={env:POSTGRESQL_URI:postgresql://}
mysql: TRYTOND_DATABASE_URI={env:MYSQL_URI:mysql://}
sqlite: DB_NAME={env:SQLITE_NAME::memory:}
postgresql: DB_NAME={env:POSTGRESQL_NAME:test}
mysql: DB_NAME={env:MYSQL_NAME:test}
install_command = pip install --pre --find-links https://trydevpi.tryton.org/ --process-dependency-links {opts} {packages}

View File

@ -1,5 +1,5 @@
[tryton]
version=4.1.0
version=4.7.0
depends:
production
stock_lot