add work station and task for ldms production

This commit is contained in:
Wilson Gomez 2023-06-15 17:26:17 -05:00
parent 7f9492130f
commit cc2ccd69ad
16 changed files with 305 additions and 54 deletions

View File

@ -10,6 +10,7 @@ from . import invoice
from . import agent from . import agent
from . import shop from . import shop
from . import dash from . import dash
from . import bom
def register(): def register():
@ -25,7 +26,11 @@ def register():
sale.SaleMove, sale.SaleMove,
sale.OrderStatusTime, sale.OrderStatusTime,
shop.SaleShop, shop.SaleShop,
production.Production, bom.BOM,
production.WorkStation,
production.WorkStationPrinter,
production.ConfigurationTask,
production.Task,
product.ProductMixOption, product.ProductMixOption,
product.Product, product.Product,
invoice.InvoiceLine, invoice.InvoiceLine,

8
bom.py
View File

@ -11,11 +11,5 @@ def round_dec(number):
class BOM(metaclass=PoolMeta): class BOM(metaclass=PoolMeta):
__name__ = 'production.bom' __name__ = 'production.bom'
inputs_cost_price = fields.Function(fields.Numeric('Inputs Cost Price'),
'get_inputs_cost_price')
def get_inputs_cost_price(self, name): tasks_configuration = fields.One2Many('production.configuration_task', 'ldm', 'Tasks Configuration')
total_cost = 0
for _in in self.inputs:
total_cost += round_dec(_in.product.cost_price * Decimal(_in.quantity))
return total_cost

View File

@ -3,7 +3,7 @@
this repository contains the full copyright notices and license terms. --> this repository contains the full copyright notices and license terms. -->
<tryton> <tryton>
<data> <data>
<record model="ir.ui.view" id="bom_service_view_tree"> <!-- <record model="ir.ui.view" id="bom_service_view_tree">
<field name="model">production.bom.service</field> <field name="model">production.bom.service</field>
<field name="type">tree</field> <field name="type">tree</field>
<field name="name">bom_service_tree</field> <field name="name">bom_service_tree</field>
@ -13,7 +13,7 @@ this repository contains the full copyright notices and license terms. -->
<field name="model">production.bom.service</field> <field name="model">production.bom.service</field>
<field name="type">form</field> <field name="type">form</field>
<field name="name">bom_service_form</field> <field name="name">bom_service_form</field>
</record> </record> -->
<record model="ir.ui.view" id="bom_view_form"> <record model="ir.ui.view" id="bom_view_form">
<field name="model">production.bom</field> <field name="model">production.bom</field>

View File

@ -8,6 +8,7 @@ class Product(metaclass=PoolMeta):
__name__ = 'product.product' __name__ = 'product.product'
products_mix = fields.Many2Many('product.product-mix.option', products_mix = fields.Many2Many('product.product-mix.option',
'product', 'option', 'Mix') 'product', 'option', 'Mix')
tasks = fields.One2Many('production.configuration_task', 'product', 'Tasks')
class ProductMixOption(ModelSQL): class ProductMixOption(ModelSQL):

View File

@ -1,47 +1,104 @@
# This file is part of Tryton. The COPYRIGHT file at the top level of # This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms. # this repository contains the full copyright notices and license terms.
# from trytond.pyson import Eval # from trytond.pyson import Eval
# from trytond.model import fields from trytond.model import fields, ModelSQL, ModelView
from trytond.transaction import Transaction from trytond.transaction import Transaction
from decimal import Decimal from decimal import Decimal
from trytond.pool import PoolMeta, Pool from trytond.pool import PoolMeta, Pool
from trytond.pyson import Eval
def round_dec(number): def round_dec(number):
return Decimal(number.quantize(Decimal('.01'))) return Decimal(number.quantize(Decimal('.01')))
class Production(metaclass=PoolMeta): STATES= {'required': True}
__name__ = 'production'
class WorkStation(ModelSQL, ModelView):
"Work Station"
__name__ = 'production.workstation'
name = fields.Char('Name', states=STATES)
code = fields.Char('Code', states=STATES)
printers = fields.Many2Many('production.workstation.pos_printer', 'work_station', 'printer', 'Printers')
class WorkStationPrinter(ModelSQL, ModelView):
"Work Station"
__name__ = 'production.workstation.pos_printer'
work_station = fields.Many2One('production.workstation', 'Work Station')
printer = fields.Many2One('sale.pos_printer', 'Printer')
class ConfigurationTask(ModelSQL, ModelView):
"Configuration Task"
__name__ = 'production.configuration_task'
name = fields.Char('Name', states=STATES)
description = fields.Text('Description')
ldm = fields.Many2One('production.bom', 'LDM', states=STATES)
product = fields.Many2One('product.product', 'Product',
search_context={
'outputs': Eval('_parent_ldm', {}).get('outputs'),
})
work_station = fields.Many2One('production.workstation', 'Work Station', states=STATES)
@fields.depends('ldm', 'product', '_parent_ldm.outputs')
def on_change_ldm(self):
print(self.ldm, 'valid')
if self.ldm:
self.product = self.ldm.outputs[0].product
class Task(ModelSQL, ModelView):
"Task"
__name__ = 'production.task'
name = fields.Char('Name', states=STATES)
description = fields.Text('Description')
ldm = fields.Many2One('production.bom', 'LDM', states=STATES)
work_station = fields.Many2One('production.workstation', 'Work Station', states=STATES)
planned_date = fields.Date('Planned Date')
quantity = fields.Integer('Quantity')
state = fields.Selection([('pending', 'Pending'), ('done', 'Done')], 'State')
@classmethod @classmethod
def __setup__(cls): def __setup__(cls):
super(Production, cls).__setup__() super(Task, cls).__setup__()
def create_account_move_stock(self, kind):
if kind == 'assigned':
return
pool = Pool()
Move = pool.get('account.move')
Line = pool.get('account.move.line')
Period = pool.get('account.period')
Journal = pool.get('account.journal')
Period = pool.get('account.period')
company_id = Transaction().context.get('company')
company = pool.get('company.company')(company_id)
company_party = company.party
journals = Journal.search([ # class Production(metaclass=PoolMeta):
('code', '=', 'STO') # __name__ = 'production'
])
if journals: # @classmethod
journal = journals[0] # def __setup__(cls):
# super(Production, cls).__setup__()
if not self.planned_date: # def create_account_move_stock(self, kind):
self.raise_user_error('planned_date_required') # if kind == 'assigned':
# return
# pool = Pool()
# Move = pool.get('account.move')
# Line = pool.get('account.move.line')
# Period = pool.get('account.period')
# Journal = pool.get('account.journal')
# Period = pool.get('account.period')
# company_id = Transaction().context.get('company')
# company = pool.get('company.company')(company_id)
# company_party = company.party
lines = [] # journals = Journal.search([
balance = Decimal(0) # ('code', '=', 'STO')
# ])
# if journals:
# journal = journals[0]
# if not self.planned_date:
# self.raise_user_error('planned_date_required')
# lines = []
# balance = Decimal(0)
# FIXME # FIXME
# for _in in self.inputs: # for _in in self.inputs:
# if _in.product.cost_price == 0: # if _in.product.cost_price == 0:

View File

@ -4,21 +4,94 @@ this repository contains the full copyright notices and license terms. -->
<tryton> <tryton>
<data> <data>
<record model="ir.ui.view" id="production_view_form"> <!-- <record model="ir.ui.view" id="production_view_form">
<field name="model">production</field> <field name="model">production</field>
<field name="inherit" ref="production.production_view_form"/> <field name="inherit" ref="production.production_view_form"/>
<field name="name">production_form</field> <field name="name">production_form</field>
</record> </record>
<record model="ir.action.wizard" id="act_done_productions"> <record model="ir.action.wizard" id="act_done_productions">
<field name="name">Done Productions</field> <field name="name">Done Productions</field>
<field name="wiz_name">production.done_productions</field> <field name="wiz_name">production.done_productions</field>
</record> </record>
<record model="ir.action.keyword" id="action_done_productions_keyword"> <record model="ir.action.keyword" id="action_done_productions_keyword">
<field name="keyword">form_action</field> <field name="keyword">form_action</field>
<field name="model">production,-1</field> <field name="model">production,-1</field>
<field name="action" ref="act_done_productions"/> <field name="action" ref="act_done_productions"/>
</record> </record> -->
<!-- work station -->
<record model="ir.ui.view" id="production_workstation_view_form">
<field name="model">production.workstation</field>
<field name="type">form</field>
<field name="name">production_workstation_view_form</field>
</record>
<record model="ir.ui.view" id="production_workstation_view_tree">
<field name="model">production.workstation</field>
<field name="type">tree</field>
<field name="name">production_workstation_view_tree</field>
</record>
<record model="ir.action.act_window" id="act_production_workstation">
<field name="name">Work Stations</field>
<field name="res_model">production.workstation</field>
</record>
<record model="ir.action.act_window.view" id="act_production_workstation_tree_view">
<field name="sequence" eval="10"/>
<field name="view" ref="production_workstation_view_tree"/>
<field name="act_window" ref="act_production_workstation"/>
</record>
<record model="ir.action.act_window.view" id="act_production_workstation_form_view">
<field name="sequence" eval="20"/>
<field name="view" ref="production_workstation_view_form"/>
<field name="act_window" ref="act_production_workstation"/>
</record>
<menuitem parent="production.menu_configuration"
action="act_production_workstation" sequence="130"
id="menu_production_workstation" icon="tryton-list"/>
<!-- configuration task views-->
<record model="ir.ui.view" id="configuration_task_tree">
<field name="model">production.configuration_task</field>
<field name="type">tree</field>
<field name="name">configuration_task_tree</field>
</record>
<record model="ir.ui.view" id="configuration_task_form">
<field name="model">production.configuration_task</field>
<field name="type">form</field>
<field name="name">configuration_task_form</field>
</record>
<!-- task views -->
<record model="ir.ui.view" id="production_task_view_form">
<field name="model">production.task</field>
<field name="type">form</field>
<field name="name">production_task_view_form</field>
</record>
<record model="ir.ui.view" id="production_task_view_tree">
<field name="model">production.task</field>
<field name="type">tree</field>
<field name="name">production_task_view_tree</field>
</record>
<record model="ir.action.act_window" id="act_production_task">
<field name="name">Tasks</field>
<field name="res_model">production.task</field>
</record>
<record model="ir.action.act_window.view" id="act_production_task_tree_view">
<field name="sequence" eval="10"/>
<field name="view" ref="production_task_view_tree"/>
<field name="act_window" ref="act_production_task"/>
</record>
<record model="ir.action.act_window.view" id="act_production_task_form_view">
<field name="sequence" eval="20"/>
<field name="view" ref="production_task_view_form"/>
<field name="act_window" ref="act_production_task"/>
</record>
<menuitem parent="production.menu_production"
action="act_production_task" sequence="150"
id="menu_production_task" icon="tryton-list"/>
</data> </data>
</tryton> </tryton>

43
sale.py
View File

@ -11,6 +11,7 @@ from trytond.transaction import Transaction
from trytond.wizard import ( from trytond.wizard import (
Wizard, StateTransition, StateView, Button, StateReport Wizard, StateTransition, StateView, Button, StateReport
) )
from operator import attrgetter
from decimal import Decimal from decimal import Decimal
from trytond.wizard import StateReport from trytond.wizard import StateReport
from trytond.report import Report from trytond.report import Report
@ -88,6 +89,43 @@ class Sale(metaclass=PoolMeta):
if tables: if tables:
ShopTable.write(tables, {'sale': None, 'state':'available'}) ShopTable.write(tables, {'sale': None, 'state':'available'})
def get_data_for_stations(self):
TaskConfig = Pool().get('production.configuration_task')
Line = Pool().get('sale.line')
data_grouped_printer = {}
data_sale = {'number': self.number }
shop = self.shop
line_commanded = []
for line in self.lines:
if line.status_order in ('draft', 'requested'):
line_commanded.append(line.id)
qty = line.quantity
tasks = line.product.tasks
att_getter = attrgetter("name", "description")
att_getter_p = attrgetter("host", "interface", "port", "row_characters")
for t in tasks:
name, description = att_getter(t)
value = {'name': name, 'description': description, 'qty': qty}
for p in t.work_station.printers:
printer_id = p.id
if p.shop == shop:
try:
data_grouped_printer[printer_id]['lines'].append(value)
except:
host, interface, port, row_characters = att_getter_p(p)
value_printer = {
'device': host,
'interface': interface,
'profile': '',
'row_characters': row_characters
}
data_grouped_printer[printer_id] = {}
data_grouped_printer[printer_id]['printer'] = value_printer
data_grouped_printer[printer_id]['sale'] = data_sale
data_grouped_printer[printer_id]['lines'] = [value]
Line.write(line_commanded, {'status_order': 'commanded'})
return data_grouped_printer
@classmethod @classmethod
def delete(cls, sales): def delete(cls, sales):
for sale in sales: for sale in sales:
@ -343,6 +381,11 @@ class OrderStatusTime(ModelSQL, ModelView):
class SaleLine(metaclass=PoolMeta): class SaleLine(metaclass=PoolMeta):
__name__ = 'sale.line' __name__ = 'sale.line'
production = fields.Many2One('production', 'Production') production = fields.Many2One('production', 'Production')
status_order = fields.Selection(OPTIONS_STATUS, 'Status Order')
@staticmethod
def default_status_order():
return 'draft'
@classmethod @classmethod
def delete(cls, lines): def delete(cls, lines):

View File

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

View File

@ -11,6 +11,8 @@ xml:
restaurant.xml restaurant.xml
sale.xml sale.xml
product.xml product.xml
production.xml
bom.xml
agent.xml agent.xml
shop.xml shop.xml
message.xml message.xml

11
view/bom_form.xml Normal file
View File

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<!-- This file is part of Tryton. The COPYRIGHT file at the top level of
this repository contains the full copyright notices and license terms. -->
<data>
<xpath expr="/form/notebook/page[@id='lines']" position="after">
<page string="Tasks Configuration" id="tasks">
<field name="tasks_configuration" colspan="4"
view_ids="sale_pos_frontend_rest.configuration_task_tree,sale_pos_frontend_rest.configuration_task_form"/>
</page>
</xpath>
</data>

View File

@ -0,0 +1,14 @@
<?xml version="1.0"?>
<!-- This file is part sale_shop module for Tryton.
The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
<form>
<label name="name"/>
<field name="name"/>
<label name="ldm"/>
<field name="ldm"/>
<label name="work_station"/>
<field name="work_station"/>
<newline/>
<label name="description"/>
<field name="description" colspan="4"/>
</form>

View File

@ -0,0 +1,8 @@
<?xml version="1.0"?>
<!-- This file is part sale_shop module for Tryton.
The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
<tree>
<field name="name"/>
<field name="ldm"/>
<field name="work_station"/>
</tree>

View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<!-- This file is part sale_shop module for Tryton.
The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
<form>
<label name="name"/>
<field name="name"/>
<label name="ldm"/>
<field name="ldm"/>
<label name="work_station"/>
<field name="work_station"/>
<label name="quantity"/>
<field name="quantity"/>
<label name="planned_date"/>
<field name="planned_date"/>
<newline/>
<label name="description"/>
<field name="description" colspan="4"/>
<label name="state"/>
<field name="state"/>
</form>

View File

@ -0,0 +1,11 @@
<?xml version="1.0"?>
<!-- This file is part sale_shop module for Tryton.
The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
<tree>
<field name="name"/>
<field name="ldm"/>
<field name="work_station"/>
<field name="planned_date"/>
<field name="quantity"/>
<field name="state"/>
</tree>

View File

@ -0,0 +1,10 @@
<?xml version="1.0"?>
<!-- This file is part sale_shop module for Tryton.
The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
<form>
<label name="name"/>
<field name="name"/>
<label name="code"/>
<field name="code"/>
<field name="printers" colspan="4"/>
</form>

View File

@ -0,0 +1,7 @@
<?xml version="1.0"?>
<!-- This file is part sale_shop module for Tryton.
The COPYRIGHT file at the top level of this repository contains the full copyright notices and license terms. -->
<tree>
<field name="name"/>
<field name="code"/>
</tree>