Add cost lines on farrowing, move, transformation and weaning events

This commit is contained in:
Sergi Almacellas Abellana 2014-04-14 11:09:19 +02:00
parent af1a68bbb2
commit 325852b2b6
18 changed files with 5494 additions and 37 deletions

View File

@ -5,6 +5,7 @@ from trytond.pool import Pool
from .animal import *
from .animal_group import *
from .events import *
from .product import *
from .production import *
from .quality import *
from .specie import *
@ -38,8 +39,10 @@ def register():
LotAnimal,
LotAnimalGroup,
Lot,
LotCostLine,
User,
UserLocation,
Template,
EventOrder,
AbstractEvent,
MoveEvent,

View File

@ -391,13 +391,15 @@ class Animal(ModelSQL, ModelView, AnimalMixin):
})
lot_tmp = Lot(product=product)
cost_lines = lot_tmp._on_change_product_cost_lines()
return {
res = {
'number': animal_vals['number'],
'product': product.id,
'animal_type': animal_vals['type'],
'cost_lines': [('create', cost_lines.get('add', []))],
}
if Transaction().context.get('create_cost_lines', True):
cost_lines = lot_tmp._on_change_product_cost_lines()
res['cost_lines'] = [('create', cost_lines.get('add', []))]
return res
@classmethod
def delete(cls, animals):

View File

@ -124,7 +124,8 @@ class FarrowingEvent(AbstractEvent):
if farrowing_event.live != 0:
with Transaction().set_context(
no_create_stock_move=True):
no_create_stock_move=True,
create_cost_lines=False):
produced_group = farrowing_event._get_produced_group()
produced_group.save()
farrowing_event.produced_group = produced_group
@ -153,7 +154,24 @@ class FarrowingEvent(AbstractEvent):
def _get_event_move(self):
pool = Pool()
Move = pool.get('stock.move')
ModelData = pool.get('ir.model.data')
LotCostLine = pool.get('stock.lot.cost_line')
category_id = ModelData.get_id('farm', 'cost_category_farrowing_cost')
context = Transaction().context
lot = self.produced_group.lot
if lot and lot.product.template.farrowing_price:
if lot.cost_lines:
cost_line = lot.cost_lines[0]
else:
cost_line = LotCostLine()
cost_line.lot = self.produced_group.lot
cost_line.category = category_id
cost_line.origin = str(self)
cost_line.unit_price = lot.product.template.farrowing_price
cost_line.save()
return Move(
product=self.specie.group_product.id,
uom=self.specie.group_product.default_uom.id,

View File

@ -224,11 +224,23 @@ class MoveEvent(AbstractEvent):
def _get_event_move(self):
pool = Pool()
Move = pool.get('stock.move')
ModelData = pool.get('ir.model.data')
LotCostLine = pool.get('stock.lot.cost_line')
category_id = ModelData.get_id('stock_lot_cost',
'cost_category_standard_price')
context = Transaction().context
lot = (self.animal_type != 'group' and self.animal.lot or
self.animal_group.lot)
if lot and lot.cost_price != self.unit_price:
cost_line = LotCostLine()
cost_line.lot = lot
cost_line.category = category_id
cost_line.origin = str(self)
cost_line.unit_price = self.unit_price - lot.cost_price
cost_line.save()
return Move(
product=lot.product,
uom=lot.product.default_uom,

View File

@ -335,6 +335,7 @@ class TransformationEvent(AbstractEvent):
lot = self.to_animal_group.lot
else:
lot = self.to_animal.lot
production_location = self.farm.production_location
return Move(
@ -346,7 +347,7 @@ class TransformationEvent(AbstractEvent):
planned_date=self.timestamp.date(),
effective_date=self.timestamp.date(),
company=context.get('company'),
lot=lot.id,
lot=lot,
unit_price=lot.product.cost_price,
origin=self,
)

View File

@ -228,13 +228,18 @@ class WeaningEvent(AbstractEvent):
weaning_event.weaned_move = weaned_move
todo_moves.append(weaned_move)
cost_line = weaning_event._get_weaning_cost_line()
if cost_line:
cost_line.save()
weaning_event.save()
current_cycle.update_state(weaning_event)
if todo_moves:
Move.assign(todo_moves)
Move.do(todo_moves)
if todo_trans_events:
TransformationEvent.validate_event(todo_trans_events)
with Transaction().set_context(create_cost_lines=False):
TransformationEvent.validate_event(todo_trans_events)
def _get_female_move(self):
pool = Pool()
@ -275,6 +280,23 @@ class WeaningEvent(AbstractEvent):
lot=self.farrowing_group.lot,
origin=self)
def _get_weaning_cost_line(self):
pool = Pool()
ModelData = pool.get('ir.model.data')
LotCostLine = pool.get('stock.lot.cost_line')
category_id = ModelData.get_id('farm', 'cost_category_weaning_cost')
group = (self.weaned_group if self.weaned_group
else self.farrowing_group)
if (group.lot and group.lot.product.weaning_price and
group.lot.product.weaning_price != group.lot.cost_price):
cost_line = LotCostLine()
cost_line.lot = group.lot
cost_line.category = category_id
cost_line.origin = str(self)
cost_line.unit_price = (group.lot.product.weaning_price -
group.lot.cost_price)
return cost_line
def _get_weaned_move(self):
pool = Pool()
Move = pool.get('stock.move')

5231
locale/ca_ES.po Normal file

File diff suppressed because it is too large Load Diff

View File

@ -1325,10 +1325,9 @@ msgctxt "field:farm.event.order,timestamp:"
msgid "Date & Time"
msgstr "Fecha & Hora"
#, fuzzy
msgctxt "field:farm.event.order,weaning_events:"
msgid "Weaning Events"
msgstr "Weaning Events"
msgstr "Eventos de destete"
#, fuzzy
msgctxt "field:farm.event.order,write_date:"
@ -3153,7 +3152,6 @@ msgctxt "field:farm.specie.farm_line,has_female:"
msgid "Females"
msgstr "Hembras"
#, fuzzy
msgctxt "field:farm.specie.farm_line,has_group:"
msgid "Groups"
msgstr "Grupos"
@ -3490,6 +3488,14 @@ msgctxt "field:ir.ui.menu,specie:"
msgid "Specie"
msgstr "Especie"
msgctxt "field:product.template,farrowing_price:"
msgid "Farrowing Price"
msgstr "Precio de parto"
msgctxt "field:product.template,weaning_price:"
msgid "Weaning Price"
msgstr "Precio destete"
msgctxt "field:production.bom,semen_dose:"
msgid "Semen Dose"
msgstr "Dosis de semen"
@ -3789,6 +3795,8 @@ msgstr "El número de animales en el grupo cuando éste nació o fué comprado."
msgctxt "help:farm.animal.group,locations:"
msgid "Farms where this group can be found. It is used for access management."
msgstr ""
"Granjas a las que tienen acceso los miembros de este grupo. Se usa para la "
"gestión del acceso."
msgctxt "help:farm.animal.group,origin:"
msgid ""
@ -4089,6 +4097,22 @@ msgstr ""
"Grupo al que se añadirán los animales destetados. Si se deja en blanco se "
"mantendrán en el mismo grupo."
msgctxt "help:product.template,farrowing_price:"
msgid ""
"Unitary cost for farrowing events. It's only used when the product is a "
"group product of a farm specie."
msgstr ""
"Coste unitario de los eventos de aparto. Solo se utiliza en caso que el "
"producto se el definido como grupo de una especie de una granja."
msgctxt "help:product.template,weaning_price:"
msgid ""
"Unitary cost for weaning events. It's only used when the product is a group "
"product of a farm specie."
msgstr ""
"Coste unitario de los eventos de destete. Solo se utiliza en caso que el "
"producto se el definido como grupo de una especie de una granja."
msgctxt "help:res.user,farms:"
msgid ""
"Farms to which this user is assigned. Determine animals that he/she can "
@ -4111,7 +4135,7 @@ msgstr "Indica que la ubicación es un silo."
msgctxt "model:farm.abort.event,name:"
msgid "Farm Abort Event"
msgstr "Evento de aborto (Granja)"
msgstr "Evento de aborto"
msgctxt "model:farm.abort.event-farm.animal.female_cycle,name:"
msgid "Abort Event - Female Cycle"
@ -4119,7 +4143,7 @@ msgstr "Evento de aborto - Ciclo hembra"
msgctxt "model:farm.animal,name:"
msgid "Farm Animal"
msgstr "Animal (Granja)"
msgstr "Animal"
msgctxt "model:farm.animal-farm.tag,name:"
msgid "Animal - Tag"
@ -4127,11 +4151,11 @@ msgstr "Animal - Etiqueta"
msgctxt "model:farm.animal.female_cycle,name:"
msgid "Farm Female Cycle"
msgstr "Ciclo hembras (Granja)"
msgstr "Ciclo hembras"
msgctxt "model:farm.animal.group,name:"
msgid "Group of Farm Animals"
msgstr "Grupo de animales (granja)"
msgstr "Grupo de animales"
msgctxt "model:farm.animal.group-farm.tag,name:"
msgid "Animal Group - Tag"
@ -4139,11 +4163,11 @@ msgstr "Grupo animales - Etiqueta"
msgctxt "model:farm.animal.group.weight,name:"
msgid "Farm Animal Group Weight Record"
msgstr "Registro peso grupo de animales (Granja)"
msgstr "Registro peso grupo de animales"
msgctxt "model:farm.animal.weight,name:"
msgid "Farm Animal Weight Record"
msgstr "Registro peso animal (granja)"
msgstr "Registro peso animal"
msgctxt "model:farm.event,name:"
msgid "Event"
@ -4151,11 +4175,11 @@ msgstr "Evento"
msgctxt "model:farm.event.order,name:"
msgid "Farm Events Work Order"
msgstr "Orden de trabajo eventos (Granja)"
msgstr "Orden de trabajo eventos"
msgctxt "model:farm.farrowing.event,name:"
msgid "Farm Farrowing Event"
msgstr "Evento de parto (Granja)"
msgstr "Evento de parto"
msgctxt "model:farm.farrowing.event-farm.animal.female_cycle,name:"
msgid "Farrowing Event - Female Cycle"
@ -4167,7 +4191,7 @@ msgstr "Evento de parto - Grupo de animales"
msgctxt "model:farm.farrowing.problem,name:"
msgid "Farrowing Event Problem"
msgstr "Problema en evento de parto (Granja)"
msgstr "Problema en evento de parto"
msgctxt "model:farm.farrowing.problem,name:farrowing_no_problems"
msgid "No problems"
@ -4221,11 +4245,11 @@ msgstr "Inventario provisional de pienso - Ubicación"
msgctxt "model:farm.foster.event,name:"
msgid "Farm Foster Event"
msgstr "Evento de adopción (Granja)"
msgstr "Evento de adopción"
msgctxt "model:farm.insemination.event,name:"
msgid "Farm Insemination Event"
msgstr "Evento de inseminación (Granja)"
msgstr "Evento de inseminación"
msgctxt "model:farm.medication.event,name:"
msgid "Medication Event"
@ -4233,15 +4257,15 @@ msgstr "Evento de medicación"
msgctxt "model:farm.move.event,name:"
msgid "Farm Move Event"
msgstr "Evento de movimiento (Granja)"
msgstr "Evento de movimiento"
msgctxt "model:farm.pregnancy_diagnosis.event,name:"
msgid "Farm Pregnancy Diagnosis Event"
msgstr "Evento de diagnosis de embarazo (Granja)"
msgstr "Evento de diagnosis de embarazo"
msgctxt "model:farm.removal.event,name:"
msgid "Farm Removal Event"
msgstr "Evento de eliminación (Granja)"
msgstr "Evento de eliminación"
msgctxt "model:farm.removal.reason,name:"
msgid "Removal Event Reason"
@ -4277,7 +4301,7 @@ msgstr "Tipo (Evento de eliminación)"
msgctxt "model:farm.removal.type,name:removal_type_death_on_farm"
msgid "Death on Farm"
msgstr "Tipo de muerte (Granja)"
msgstr "Tipo de muerte"
msgctxt "model:farm.removal.type,name:removal_type_export"
msgid "Export"
@ -4329,15 +4353,15 @@ msgstr "Granja gestionada por especie"
msgctxt "model:farm.tag,name:"
msgid "Farm Tags"
msgstr "Etiquetas (granja)"
msgstr "Etiquetas"
msgctxt "model:farm.transformation.event,name:"
msgid "Farm Transformation Event"
msgstr "Evento de transformación (Granja)"
msgstr "Evento de transformación"
msgctxt "model:farm.weaning.event,name:"
msgid "Farm Weaning Event"
msgstr "Evento de destete (Granja)"
msgstr "Evento de destete"
msgctxt "model:farm.weaning.event-farm.animal.female_cycle,name:"
msgid "Weaning Event - Female Cycle"
@ -4441,22 +4465,21 @@ msgctxt "model:ir.action,name:act_farm_transformation_event"
msgid "Transformation Events"
msgstr "Eventos de transformación"
#, fuzzy
msgctxt "model:ir.action,name:act_farm_weaning_event"
msgid "Weaning Events"
msgstr "Weaning Events"
msgstr "Eventos de destete"
msgctxt "model:ir.sequence.type,name:sequence_type_animal"
msgid "Farm Animal"
msgstr "Animal (Granja)"
msgstr "Animal"
msgctxt "model:ir.sequence.type,name:sequence_type_animal_group"
msgid "Farm Animal Group"
msgstr "Grupo de animales (Granja)"
msgstr "Grupo de animales"
msgctxt "model:ir.sequence.type,name:sequence_type_event_order"
msgid "Farm Event Order"
msgstr "Orden de evento (Granja)"
msgstr "Orden de evento"
msgctxt "model:ir.sequence.type,name:sequence_type_lot"
msgid "Stock Lot"
@ -4534,6 +4557,14 @@ msgctxt "model:stock.lot-farm.animal.group,name:"
msgid "Lot - Animal Group"
msgstr "Lote - Grupo de animales"
msgctxt "model:stock.lot.cost_category,name:cost_category_farrowing_cost"
msgid "Farrowing Cost"
msgstr "Coste de parto"
msgctxt "model:stock.lot.cost_category,name:cost_category_weaning_cost"
msgid "Weaning Cost"
msgstr "Coste destete"
msgctxt "selection:farm.abort.event,animal_type:"
msgid "Female"
msgstr "Hembra"
@ -4717,10 +4748,9 @@ msgctxt "selection:farm.event.order,event_type:"
msgid "Pregnancy Diagnosis"
msgstr "Diagnóstico de gestación"
#, fuzzy
msgctxt "selection:farm.event.order,event_type:"
msgid "Weanings"
msgstr "Weanings"
msgstr "Destetes"
msgctxt "selection:farm.farrowing.event,animal_type:"
msgid "Female"
@ -5182,11 +5212,11 @@ msgstr "¿Está seguro de validar este evento?"
msgctxt "view:farm.event:"
msgid "Farm Event"
msgstr "Evento (Granja)"
msgstr "Evento"
msgctxt "view:farm.event:"
msgid "Farm Events"
msgstr "Órdenes de evento (Granja)"
msgstr "Órdenes de evento"
msgctxt "view:farm.event:"
msgid "_Validate"

18
product.py Normal file
View File

@ -0,0 +1,18 @@
#The COPYRIGHT file at the top level of this repository contains the full
#copyright notices and license terms.
from trytond.model import fields
from trytond.pool import PoolMeta
__all__ = ['Template']
__metaclass__ = PoolMeta
class Template:
__name__ = 'product.template'
farrowing_price = fields.Numeric('Farrowing Price', digits=(16, 4),
help=('Unitary cost for farrowing events. It\'s only used when the '
'product is a group product of a farm specie.'))
weaning_price = fields.Numeric('Weaning Price', digits=(16, 4),
help=('Unitary cost for weaning events. It\'s only used when the '
'product is a group product of a farm specie.'))

13
product.xml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<!-- The COPYRIGHT file at the top level of this repository contains the full
copyright notices and license terms. -->
<tryton>
<data>
<record model="ir.ui.view" id="product_template_form_view">
<field name="model">product.template</field>
<field name="type">form</field>
<field name="inherit" ref="product.template_view_form"/>
<field name="name">template_form</field>
</record>
</data>
</tryton>

View File

@ -10,7 +10,7 @@ from trytond.pool import Pool, PoolMeta
from trytond.transaction import Transaction
__all__ = ['Location', 'LocationSiloLocation', 'Lot', 'LotAnimal',
'LotAnimalGroup', 'Move']
'LotAnimalGroup', 'Move', 'LotCostLine']
__metaclass__ = PoolMeta
@ -418,3 +418,18 @@ class Move:
move.lot.animal.location = move.to_location.id
move.lot.animal.save()
return res
class LotCostLine:
__name__ = 'stock.lot.cost_line'
@classmethod
def _get_origin(cls):
models = super(LotCostLine, cls)._get_origin()
models += [
'farm.move.event',
'farm.transformation.event',
'farm.farrowing.event',
'farm.weaning.event',
]
return models

View File

@ -25,4 +25,14 @@
<field name="name">stock_location_list</field>
</record>
</data>
<data noupdate="1">
<record model="stock.lot.cost_category"
id="cost_category_farrowing_cost">
<field name="name">Farrowing Cost</field>
</record>
<record model="stock.lot.cost_category"
id="cost_category_weaning_cost">
<field name="name">Weaning Cost</field>
</record>
</data>
</tryton>

View File

@ -81,6 +81,7 @@ Create specie's products::
... default_uom=unit,
... type='goods',
... list_price=Decimal('30'),
... farrowing_price=Decimal('10'),
... cost_price=Decimal('20'))
>>> group_template.save()
>>> group_product = Product(template=group_template)
@ -371,3 +372,11 @@ it is 'mated' and check female functional fields values::
7
>>> female.current_cycle.dead
2
Female childs must have the farrowing cost::
>>> group = farrow_event2.produced_group
>>> len(group.lot.cost_lines)
1
>>> group.lot.cost_price == Decimal('10.0')
True

View File

@ -200,6 +200,38 @@ Validate individual move event::
>>> individual.current_weight.weight
Decimal('80.50')
Create individual move event changing cost price::
>>> individual.lot.cost_price == Decimal('25.0')
True
>>> move_individual = MoveEvent(
... animal_type='individual',
... specie=pigs_specie,
... farm=warehouse,
... animal=individual,
... timestamp=now,
... from_location=individual.location,
... to_location=location1_id)
>>> move_individual.unit_price = Decimal('30.0')
>>> move_individual.save()
>>> move_individual.unit_price == Decimal('30.0')
True
>>> MoveEvent.validate_event([move_individual.id], config.context)
>>> move_individual.reload()
>>> move_individual.state
u'validated'
>>> individual.reload()
>>> individual.location.id == location1_id
True
>>> individual.lot.cost_price == Decimal('30.0')
True
>>> move_cost_line, = [x for x in individual.lot.cost_lines
... if x.origin == move_individual]
>>> move_cost_line.unit_price == Decimal('5.0')
True
Create group::
>>> AnimalGroup = Model.get('farm.animal.group')

View File

@ -256,6 +256,10 @@ Validate transformation event::
1
>>> to_animal.type
u'individual'
>>> len(to_animal.lot.cost_lines) == 1
True
>>> to_animal.lot.cost_price == individual_template.cost_price
True
>>> to_animal.location == transform_male_to_individual.to_location
True
>>> male_to_individual.reload()

View File

@ -81,6 +81,8 @@ Create specie's products::
... default_uom=unit,
... type='goods',
... list_price=Decimal('30'),
... farrowing_price=Decimal('10'),
... weaning_price=Decimal('15'),
... cost_price=Decimal('20'))
>>> group_template.save()
>>> group_product = Product(template=group_template)
@ -286,6 +288,9 @@ validate them and check females state and female's live values::
>>> FarrowingEvent.validate_event(farrow_events, config.context)
>>> all(FarrowingEvent(i).state == 'validated' for i in farrow_events)
True
>>> all(FarrowingEvent(i).produced_group.lot.cost_price == Decimal('10.0')
... for i in farrow_events)
True
>>> females = [Animal(i) for i in female_ids]
>>> not any(f.current_cycle.pregnant for f in females)
True
@ -334,6 +339,15 @@ the weaning event doesn't have female, weaned nor lost moves::
>>> female1.current_cycle.weaning_event.female_move
>>> female1.current_cycle.weaning_event.weaned_move
>>> female1.current_cycle.weaning_event.lost_move
>>> lot = weaning_event1.farrowing_group.lot
>>> len(lot.cost_lines)
2
>>> lot.cost_price == Decimal('15.0')
True
>>> weaning_cost_line, = [x for x in lot.cost_lines
... if x.origin == weaning_event1]
>>> weaning_cost_line.unit_price == Decimal('5.0')
True
Create a weaning event for second female (7 lives) with 6 as quantity, with
current female location as destination of weaned group but not for destination
@ -463,4 +477,13 @@ weaned group moves::
2.0
>>> female4.current_cycle.weaning_event.transformation_event.state
u'validated'
>>> lot = weaning_event4.weaned_group.lot
>>> len(lot.cost_lines)
2
>>> lot.cost_price == Decimal('15.0')
True
>>> weaning_cost_line, = [x for x in lot.cost_lines
... if x.origin == weaning_event4]
>>> weaning_cost_line.unit_price == Decimal('-5.0')
True

View File

@ -16,6 +16,7 @@ xml:
production.xml
quality.xml
user.xml
product.xml
animal.xml
animal_group.xml
events/abstract_event.xml

13
view/template_form.xml Normal file
View File

@ -0,0 +1,13 @@
<?xml version="1.0"?>
<!-- The COPYRIGHT file at the top level of this repository contains the full
copyright notices and license terms. -->
<data>
<xpath expr="//page[@id='general']/field[@name='list_price']"
position="after">
<newline/>
<label name="farrowing_price"/>
<field name="farrowing_price"/>
<label name="weaning_price"/>
<field name="weaning_price"/>
</xpath>
</data>