Implement carrier loading reports.

This commit refs #850
This commit is contained in:
Sergio Morillo 2015-11-30 13:42:20 +01:00
parent 4687e74717
commit ebc87f0027
12 changed files with 14226 additions and 5 deletions

View File

@ -1,7 +1,8 @@
# The COPYRIGHT file at the top level of this repository contains the full
# copyright notices and license terms.
from trytond.pool import Pool
from .load import Load, LoadOrder, LoadOrderLine, LoadOrderIncoterm
from .load import (Load, LoadOrder, LoadOrderLine, LoadOrderIncoterm,
LoadSheet, CMR)
from .configuration import Configuration
from .sale import Sale, CostType, CostTemplate, CostSale, CostSaleLine
from .stock import Move
@ -25,3 +26,7 @@ def register():
CostSaleLine,
Move,
module='carrier_load', type_='model')
Pool.register(
LoadSheet,
CMR,
module='carrier_load', type_='report')

BIN
cmr.odt Normal file

Binary file not shown.

BIN
cmr_template.odt Normal file

Binary file not shown.

13950
cmr_template.svg Normal file

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 1.5 MiB

View File

@ -25,7 +25,13 @@ class Configuration:
('code', '=', 'carrier.load.order')],
required=True))
load_purchasable = fields.Boolean('Load purchasable')
cmr_instructions = fields.Text('CMR instructions', translate=True)
cmr_copies = fields.Property(fields.Integer('CMR copies', required=True))
@classmethod
def default_load_purchasable(cls):
return False
@staticmethod
def default_cmr_copies():
return 3

124
load.py
View File

@ -7,6 +7,7 @@ from itertools import groupby
from sql import Literal
from sql.aggregate import Count
from trytond.model import ModelSQL, ModelView, fields, Workflow, Model
from trytond.modules.company import CompanyReport
from trytond.pool import PoolMeta, Pool
from trytond.pyson import Eval, If, Bool
from trytond.transaction import Transaction
@ -18,7 +19,7 @@ from trytond.modules.product import price_digits
__metaclass__ = PoolMeta
__all__ = ['Load', 'LoadOrder', 'LoadOrderLine',
'LoadOrderIncoterm']
'LoadOrderIncoterm', 'LoadSheet', 'CMR']
class Load(Workflow, ModelView, ModelSQL, DockMixin):
@ -355,7 +356,8 @@ class LoadOrder(Workflow, ModelView, ModelSQL, IncotermDocumentMixin):
states={'readonly': Eval('state') != 'draft'},
depends=['state'])
party = fields.Many2One('party.party', 'Party', select=True,
states={'readonly': (Eval('state') != 'draft') | (Eval('lines', [0]))},
states={'readonly': (Eval('state') != 'draft') | (Eval('lines', [0])),
'required': Eval('state') == 'done'},
depends=['state', 'lines'])
incoterms = fields.One2Many('carrier.load.order.incoterm', 'order', 'Incoterms',
states={'readonly': ~Eval('state').in_(['draft', 'waiting']),
@ -697,6 +699,9 @@ class LoadOrderIncoterm(ModelView, ModelSQL, IncotermMixin):
order = fields.Many2One('carrier.load.order', 'Order', required=True,
ondelete='CASCADE')
def get_rec_name(self, name):
return '%s %s' % (self.rule.rec_name, self.place)
def _get_relation_version(self):
return self.order
@ -810,3 +815,118 @@ class LoadOrderLine(ModelView, ModelSQL):
if not self.moves:
return []
return [m.id for m in self.moves if m.from_location == self.order.load.warehouse_output]
class LoadSheet(CompanyReport):
"""Carrier load report"""
__name__ = 'carrier.load.sheet'
@classmethod
def get_context(cls, records, data):
report_context = super(LoadSheet, cls).get_context(records, data)
report_context['product_quantity'] = lambda order, product: \
cls.product_quantity(order, product)
products = {}
for record in list(set(records)):
for order in record.orders:
products.update({order.id: cls._get_products(order)})
report_context['order_products'] = products
return report_context
@classmethod
def _get_products(cls, order):
return list(set([l.product for l in order.lines]))
@classmethod
def product_quantity(cls, order, product):
"""Returns product quantity in load order"""
Uom = Pool().get('product.uom')
value = 0
for line in order.lines:
if line.product and line.product.id == product.id:
value += Uom.compute_qty(line.uom, line.quantity, product.default_uom)
return value
class CMR(CompanyReport):
"""CMR report"""
__name__ = 'carrier.load.order.cmr'
@classmethod
def get_context(cls, records, data):
Configuration = Pool().get('carrier.configuration')
report_context = super(CMR, cls).get_context(records, data)
report_context['delivery_address'] = lambda order: cls.delivery_address(order)
report_context['product_name'] = (
lambda product_id, order, language: cls.product_name(product_id, order, language))
report_context['product_brand'] = (
lambda product, language: cls.product_brand(product, language))
report_context['product_packages'] = (
lambda order, product, language: cls.product_packages(order, product, language))
report_context['product_packing'] = (
lambda product, language: cls.product_packing(product, language))
report_context['product_weight'] = (
lambda order, product, language: cls.product_weight(order, product, language))
report_context['product_volume'] = (
lambda order, product, language: cls.product_volume(order, product, language))
report_context['instructions'] = (
lambda order, language: cls.instructions(order, language))
products = {}
for record in list(set(records)):
products.update({record.id: cls._get_products(record)})
report_context['order_products'] = products
report_context['copies'] = Configuration(1).cmr_copies or 3
return report_context
@classmethod
def _get_products(cls, order):
return list(set([l.product for l in order.lines]))
@classmethod
def delivery_address(cls, order):
if not order.party:
return None
return order.party.address_get(type='delivery')
@classmethod
def product_name(cls, product_id, order, language):
Product = Pool().get('product.product')
with Transaction().set_context(language=language):
return Product(product_id).rec_name
@classmethod
def product_brand(cls, product, language):
return None
@classmethod
def product_packages(cls, order, product, language):
return None
@classmethod
def product_packing(cls, product, language):
return None
@classmethod
def product_weight(cls, order, product, language):
return None
@classmethod
def product_volume(cls, order, product, language):
return None
@classmethod
def instructions(cls, order, language):
Configuration = Pool().get('carrier.configuration')
with Transaction().set_context(language=language):
value = Configuration(1).cmr_instructions
if value:
value = value.splitlines()
return value or []

View File

@ -259,5 +259,29 @@ this repository contains the full copyright notices and license terms. -->
<field name="perm_create" eval="False"/>
<field name="perm_delete" eval="False"/>
</record>
<!-- Load report -->
<record model="ir.action.report" id="report_load_sheet">
<field name="name">Load sheet</field>
<field name="model">carrier.load</field>
<field name="report_name">carrier.load.sheet</field>
<field name="report">carrier_load/load_sheet.odt</field>
</record>
<record model="ir.action.keyword" id="report_load_sheet_keyword">
<field name="keyword">form_print</field>
<field name="model">carrier.load,-1</field>
<field name="action" ref="report_load_sheet"/>
</record>
<!-- Consignment note report -->
<record model="ir.action.report" id="report_cmr">
<field name="name">CMR</field>
<field name="model">carrier.load.order</field>
<field name="report_name">carrier.load.order.cmr</field>
<field name="report">carrier_load/cmr.odt</field>
</record>
<record model="ir.action.keyword" id="report_cmr_keyword">
<field name="keyword">form_print</field>
<field name="model">carrier.load.order,-1</field>
<field name="action" ref="report_cmr"/>
</record>
</data>
</tryton>

BIN
load_sheet.odt Normal file

Binary file not shown.

View File

@ -34,6 +34,18 @@ msgctxt "field:carrier.configuration,load_sequence:"
msgid "Load Sequence"
msgstr "Secuencia Carga"
msgctxt "field:carrier.configuration,load_purchasable:"
msgid "Load purchasable"
msgstr "Carga liquidable"
msgctxt "field:carrier.configuration,cmr_instructions:"
msgid "CMR Instructions"
msgstr "Instrucciones CMR"
msgctxt "field:carrier.configuration,cmr_copies:"
msgid "CMR copies"
msgstr "Copias CMR"
msgctxt "field:carrier,purchase_party:"
msgid "Purchase party"
msgstr "Tercero para compra"
@ -602,4 +614,88 @@ msgstr "Crear compra"
msgctxt "view:carrier.load.order:"
msgid "Moves"
msgstr "Movimientos"
msgstr "Movimientos"
msgctxt "model:ir.action,name:report_load_sheet"
msgid "Load sheet"
msgstr "Nota de carga"
msgctxt "odt:carrier.load.sheet:"
msgid "Phone:"
msgstr "Telf:"
msgctxt "odt:carrier.load.sheet:"
msgid "E-Mail:"
msgstr "E-Mail:"
msgctxt "odt:carrier.load.sheet:"
msgid "VAT Number:"
msgstr "CIF:"
msgctxt "odt:carrier.load.sheet:"
msgid "CARRIER LOAD"
msgstr "CARGA TRANSPORTISTA"
msgctxt "odt:carrier.load.sheet:"
msgid "Code"
msgstr "Código"
msgctxt "odt:carrier.load.sheet:"
msgid "Date"
msgstr "Fecha"
msgctxt "odt:carrier.load.sheet:"
msgid "Carrier"
msgstr "Transportista"
msgctxt "odt:carrier.load.sheet:"
msgid "Reg. Number"
msgstr "Matrícula"
msgctxt "odt:carrier.load.sheet:"
msgid "Vehicle type"
msgstr "Tipo vehículo"
msgctxt "odt:carrier.load.sheet:"
msgid "Dock"
msgstr "Muelle"
msgctxt "odt:carrier.load.sheet:"
msgid "Warehouse"
msgstr "Almacén"
msgctxt "odt:carrier.load.sheet:"
msgid "Destination"
msgstr "Destino"
msgctxt "odt:carrier.load.sheet:"
msgid "Order"
msgstr "Orden"
msgctxt "odt:carrier.load.sheet:"
msgid "Party"
msgstr "Tercero"
msgctxt "odt:carrier.load.sheet:"
msgid "Shipment address"
msgstr "Dirección envío"
msgctxt "odt:carrier.load.sheet:"
msgid "Sale"
msgstr "Venta"
msgctxt "odt:carrier.load.sheet:"
msgid "Reference"
msgstr "Referencia"
msgctxt "odt:carrier.load.sheet:"
msgid "Quantity"
msgstr "Cantidad"
msgctxt "odt:carrier.load.sheet:"
msgid "Product"
msgstr "Producto"
msgctxt "model:ir.action,name:report_cmr"
msgid "CMR"
msgstr "CMR"

View File

@ -14,7 +14,7 @@ Imports::
... create_chart, get_accounts, create_tax
>>> from.trytond.modules.account_invoice.tests.tools import \
... set_fiscalyear_invoice_sequences, create_payment_term
>>> from proteus import config, Model, Wizard
>>> from proteus import config, Model, Wizard, Report
>>> today = datetime.date.today()
Create database::
@ -208,3 +208,18 @@ Create purchase::
>>> order.reload()
>>> order.carrier_amount
Decimal('300.00')
Check reports::
>>> load_sheet = Report('carrier.load.sheet')
>>> ext, _, _, name = load_sheet.execute([load], {})
>>> ext
u'odt'
>>> name
u'Load sheet'
>>> cmr = Report('carrier.load.order.cmr')
>>> ext, _, _, name = cmr.execute([load.orders[0]], {})
>>> ext
u'odt'
>>> name
u'CMR'

View File

@ -10,6 +10,7 @@ depends:
extras_depend:
sale_cost
company_logo
xml:
carrier.xml

View File

@ -8,5 +8,9 @@ this repository contains the full copyright notices and license terms. -->
<field name="load_order_sequence"/>
<label name="load_purchasable"/>
<field name="load_purchasable"/>
<label name="cmr_copies"/>
<field name="cmr_copies"/>
<label name="cmr_instructions"/>
<field name="cmr_instructions" colspan="3"/>
</xpath>
</data>