diff --git a/__init__.py b/__init__.py index 0508d27..490b3d4 100644 --- a/__init__.py +++ b/__init__.py @@ -8,6 +8,7 @@ from .nutrition_program import * def register(): Pool.register( NutritionProgram, + StockLot, module='nutrition_program', type_='model') Pool.register( OpenBOM, diff --git a/nutrition_program.py b/nutrition_program.py index d413631..1138127 100644 --- a/nutrition_program.py +++ b/nutrition_program.py @@ -1,12 +1,13 @@ #The COPYRIGHT file at the top level of this repository contains the full #copyright notices and license terms. from trytond.model import ModelView, ModelSQL, fields -from trytond.pool import Pool +from trytond.pool import Pool, PoolMeta from trytond.pyson import Eval, PYSONEncoder from trytond.wizard import Wizard, StateAction from trytond.transaction import Transaction -__all__ = ['NutritionProgram', 'OpenBOM'] +__all__ = ['NutritionProgram', 'StockLot', 'OpenBOM'] +__metaclass__ = PoolMeta class NutritionProgram(ModelSQL, ModelView): @@ -27,10 +28,40 @@ class NutritionProgram(ModelSQL, ModelView): return self.product.boms[0].bom.id def get_rec_name(self, name=None): - return ' %s ( %s - %s) ' % (self.product.rec_name, + return '%s (%s - %s)' % (self.product.rec_name, self.start_weight or '', self.end_weight or '') +class StockLot: + __name__ = 'stock.lot' + + nutrition_program = fields.Function(fields.Many2One('nutrition.program', + 'Nutrition Program', domain=[ + ('product', '=', Eval('product')), + ], depends=['product']), 'get_nutrition_program') + + def get_nutrition_program(self, name): + pool = Pool() + Program = pool.get('nutrition.program') + + animal = self.animal_group if self.animal_group else self.animal + if not animal: + return + + domain = [('product', '=', self.product)] + if animal.current_weight: + weight = animal.current_weight.weight + domain.extend([ + ('start_weight', '<=', weight), + ('end_weight', '>=', weight), + ], ) + programs = Program.search(domain, order=[ + ('end_weight', 'DESC'), + ], limit=1) + if len(programs) > 0: + return programs[0].id + + class OpenBOM(Wizard): 'Open BOM' __name__ = 'nutrition.program.open.bom' diff --git a/nutrition_program.xml b/nutrition_program.xml index fe2abe3..5e77f13 100644 --- a/nutrition_program.xml +++ b/nutrition_program.xml @@ -18,22 +18,24 @@ Nutrition Programs nutrition.program - - + - + - + @@ -42,7 +44,8 @@ Nutrition Program Administration - + diff --git a/tests/scenario_nutrition_program.rst b/tests/scenario_nutrition_program.rst new file mode 100644 index 0000000..c019595 --- /dev/null +++ b/tests/scenario_nutrition_program.rst @@ -0,0 +1,218 @@ +==================== +Move Events Scenario +==================== + +============= +General Setup +============= + +Imports:: + + >>> import datetime + >>> from dateutil.relativedelta import relativedelta + >>> from decimal import Decimal + >>> from proteus import config, Model, Wizard + >>> now = datetime.datetime.now() + >>> yesterday = datetime.datetime.now() - relativedelta(month=1) + >>> today = datetime.date.today() + +Create database:: + + >>> config = config.set_trytond() + >>> config.pool.test = True + +Install farm:: + + >>> Module = Model.get('ir.module.module') + >>> modules = Module.find([ + ... ('name', '=', 'nutrition_program'), + ... ]) + >>> Module.install([x.id for x in modules], config.context) + >>> Wizard('ir.module.module.install_upgrade').execute('upgrade') + +Create company:: + + >>> Currency = Model.get('currency.currency') + >>> CurrencyRate = Model.get('currency.currency.rate') + >>> Company = Model.get('company.company') + >>> Party = Model.get('party.party') + >>> company_config = Wizard('company.company.config') + >>> company_config.execute('company') + >>> company = company_config.form + >>> party = Party(name='NaN·tic') + >>> party.save() + >>> company.party = party + >>> currencies = Currency.find([('code', '=', 'EUR')]) + >>> if not currencies: + ... currency = Currency(name='Euro', symbol=u'€', code='EUR', + ... rounding=Decimal('0.01'), mon_grouping='[3, 3, 0]', + ... mon_decimal_point=',') + ... currency.save() + ... CurrencyRate(date=now.date() + relativedelta(month=1, day=1), + ... rate=Decimal('1.0'), currency=currency).save() + ... else: + ... currency, = currencies + >>> company.currency = currency + >>> company_config.execute('add') + >>> company, = Company.find() + +Reload the context:: + + >>> User = Model.get('res.user') + >>> config._context = User.get_preferences(True, config.context) + +Create products:: + + >>> ProductUom = Model.get('product.uom') + >>> unit, = ProductUom.find([('name', '=', 'Unit')]) + >>> ProductTemplate = Model.get('product.template') + >>> Product = Model.get('product.product') + >>> individual_template = ProductTemplate( + ... name='Male Pig', + ... default_uom=unit, + ... type='goods', + ... list_price=Decimal('40'), + ... cost_price=Decimal('25')) + >>> individual_template.save() + >>> individual_product = Product(template=individual_template) + >>> individual_product.save() + >>> group_template = ProductTemplate( + ... name='Group of Pig', + ... default_uom=unit, + ... type='goods', + ... list_price=Decimal('30'), + ... cost_price=Decimal('20')) + >>> group_template.save() + >>> group_product = Product(template=group_template) + >>> group_product.save() + +Create sequence:: + + >>> Sequence = Model.get('ir.sequence') + >>> event_order_sequence = Sequence( + ... name='Event Order Pig Warehouse 1', + ... code='farm.event.order', + ... padding=4) + >>> event_order_sequence.save() + >>> individual_sequence = Sequence( + ... name='Individual Pig Warehouse 1', + ... code='farm.animal', + ... padding=4) + >>> individual_sequence.save() + >>> group_sequence = Sequence( + ... name='Groups Pig Warehouse 1', + ... code='farm.animal.group', + ... padding=4) + >>> group_sequence.save() + +Create specie:: + + >>> Location = Model.get('stock.location') + >>> lost_found_location, = Location.find([('type', '=', 'lost_found')]) + >>> warehouse, = Location.find([('type', '=', 'warehouse')]) + >>> Specie = Model.get('farm.specie') + >>> SpecieBreed = Model.get('farm.specie.breed') + >>> SpecieFarmLine = Model.get('farm.specie.farm_line') + >>> pigs_specie = Specie( + ... name='Pigs', + ... male_enabled=False, + ... female_enabled=False, + ... individual_enabled=True, + ... individual_product=individual_product, + ... group_enabled=True, + ... group_product=group_product, + ... removed_location=lost_found_location, + ... foster_location=lost_found_location, + ... lost_found_location=lost_found_location, + ... feed_lost_found_location=lost_found_location) + >>> pigs_specie.save() + >>> pigs_breed = SpecieBreed( + ... specie=pigs_specie, + ... name='Holland') + >>> pigs_breed.save() + >>> pigs_farm_line = SpecieFarmLine( + ... specie=pigs_specie, + ... farm=warehouse, + ... event_order_sequence=event_order_sequence, + ... has_individual=True, + ... individual_sequence=individual_sequence, + ... has_group=True, + ... group_sequence=group_sequence) + >>> pigs_farm_line.save() + +Create farm locations:: + + >>> location1_id, location2_id = Location.create([{ + ... 'name': 'Location 1', + ... 'code': 'L1', + ... 'type': 'storage', + ... 'parent': warehouse.storage_location.id, + ... }, { + ... 'name': 'Location 2', + ... 'code': 'L2', + ... 'type': 'storage', + ... 'parent': warehouse.storage_location.id, + ... }], config.context) + +Create individual:: + + >>> Animal = Model.get('farm.animal') + >>> individual = Animal( + ... type='individual', + ... specie=pigs_specie, + ... breed=pigs_breed, + ... number='0001', + ... initial_location=location1_id) + >>> individual.save() + >>> individual.location.code + u'L1' + >>> individual.farm.code + u'WH' + >>> individual.lot.nutrition_program == None + True + +Create nutrition program:: + + >>> NutritionProgram = Model.get('nutrition.program') + >>> nutrition_program = NutritionProgram( + ... start_weight=10.0, + ... end_weight=30.0, + ... product=individual_product) + >>> nutrition_program.save() + >>> individual.lot.nutrition_program == None + True + +Add weight on animal:: + + >>> AnimalWeight = Model.get('farm.animal.weight') + >>> kg, = ProductUom.find([('name', '=', 'Kilogram')]) + >>> weight = AnimalWeight(animal=individual, + ... timestamp=yesterday, + ... uom=kg, + ... weight=Decimal('15.0')) + >>> weight.save() + >>> individual.reload() + >>> individual.current_weight.weight == Decimal('15.0') + True + >>> individual.lot.nutrition_program == nutrition_program + True + +Create another nutrition program:: + + >>> nutrition_program2 = NutritionProgram( + ... start_weight=50.0, + ... end_weight=70.0, + ... product=individual_product) + >>> nutrition_program2.save() + >>> AnimalWeight = Model.get('farm.animal.weight') + >>> kg, = ProductUom.find([('name', '=', 'Kilogram')]) + >>> weight = AnimalWeight(animal=individual, + ... timestamp=now, + ... uom=kg, + ... weight=Decimal('60.0')) + >>> weight.save() + >>> individual.reload() + >>> individual.current_weight.weight == Decimal('60.0') + True + >>> individual.lot.nutrition_program == nutrition_program2 + True diff --git a/tests/test.py b/tests/test.py index 30934d9..7ee46fe 100644 --- a/tests/test.py +++ b/tests/test.py @@ -10,7 +10,7 @@ if os.path.isdir(DIR): sys.path.insert(0, os.path.dirname(DIR)) import unittest -#import doctest TODO: Remove if no sceneario needed. +import doctest import trytond.tests.test_tryton from trytond.tests.test_tryton import test_view, test_depends from trytond.backend.sqlite.database import Database as SQLiteDatabase @@ -50,10 +50,9 @@ def doctest_dropdb(test): def suite(): suite = trytond.tests.test_tryton.suite() suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestCase)) - # TODO: remove if no scenario needed. - #suite.addTests(doctest.DocFileSuite('scenario_invoice.rst', - # setUp=doctest_dropdb, tearDown=doctest_dropdb, encoding='utf-8', - # optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) + suite.addTests(doctest.DocFileSuite('scenario_nutrition_program.rst', + setUp=doctest_dropdb, tearDown=doctest_dropdb, encoding='utf-8', + optionflags=doctest.REPORT_ONLY_FIRST_FAILURE)) return suite if __name__ == '__main__': diff --git a/tryton.cfg b/tryton.cfg index 3a401bf..1b4a393 100644 --- a/tryton.cfg +++ b/tryton.cfg @@ -1,6 +1,6 @@ [tryton] version=2.9.0 depends: - production + farm xml: nutrition_program.xml diff --git a/view/nutrition_program_form.xml b/view/nutrition_program_form.xml index ef76f36..07a4d90 100644 --- a/view/nutrition_program_form.xml +++ b/view/nutrition_program_form.xml @@ -2,12 +2,12 @@
-