Merge branch 'develop'
						commit
						935f10a97c
					
				|  | @ -28,6 +28,8 @@ class MaterialType(models.Model): | ||||||
| 
 | 
 | ||||||
|     name = fields.Char(string='Bezeichnung', required=True) |     name = fields.Char(string='Bezeichnung', required=True) | ||||||
|     print_default_code = fields.Boolean(string='Drucke Artikelnummer', required=True, help='Definiert, ob die Artikelnummer gedruckt wird') |     print_default_code = fields.Boolean(string='Drucke Artikelnummer', required=True, help='Definiert, ob die Artikelnummer gedruckt wird') | ||||||
|  |     print_sales_pic = fields.Boolean(string='Drucke Artikelbild', default=True, required=False, help='Definiert, ob ein Artikelbild gedruckt wird (Angebot/Auftrag)') | ||||||
|  |     print_production_pic = fields.Boolean(string='Drucke Produktionsbild', default=False, required=False, help='Definiert, ob ein Produktionsbild gedruckt wird (Produktionsauftrag)') | ||||||
| 
 | 
 | ||||||
|     _sql_constraints = [ |     _sql_constraints = [ | ||||||
|         ('name_uniq', 'unique(name)', 'Die Bezeichnung muss eindeutig sein') |         ('name_uniq', 'unique(name)', 'Die Bezeichnung muss eindeutig sein') | ||||||
|  |  | ||||||
|  | @ -67,6 +67,7 @@ class Partner(models.Model): | ||||||
|     collective_bill = fields.Boolean(string='Sammelrechnung', default=True) |     collective_bill = fields.Boolean(string='Sammelrechnung', default=True) | ||||||
|     country_id = fields.Many2one('res.country', string='Country', ondelete='restrict', default=_default_country_id) |     country_id = fields.Many2one('res.country', string='Country', ondelete='restrict', default=_default_country_id) | ||||||
|     commission_account_ids = fields.Many2many(comodel_name='commission.account', string='Provisionsempfänger') |     commission_account_ids = fields.Many2many(comodel_name='commission.account', string='Provisionsempfänger') | ||||||
|  |     partner_flash = fields.Char() | ||||||
| 
 | 
 | ||||||
|     _sql_constraints = [ |     _sql_constraints = [ | ||||||
|         ('ref_uniq', 'unique(ref)', 'Die Interne Referenz muss eindeutig sein'), |         ('ref_uniq', 'unique(ref)', 'Die Interne Referenz muss eindeutig sein'), | ||||||
|  | @ -281,7 +282,7 @@ class Partner(models.Model): | ||||||
|             common_list.extend( |             common_list.extend( | ||||||
|                 ['name', 'ref', 'partner_sector_id', 'info_uid', 'comment', 'vat', 'property_payment_term_id', |                 ['name', 'ref', 'partner_sector_id', 'info_uid', 'comment', 'vat', 'property_payment_term_id', | ||||||
|                  'date_vat_check', 'active', 'property_product_pricelist', 'retail_partner_id', |                  'date_vat_check', 'active', 'property_product_pricelist', 'retail_partner_id', | ||||||
|                  'is_retailer', 'name2', 'carrier_id', 'collective_bill', 'fiscal_position']) |                  'is_retailer', 'name2', 'carrier_id', 'collective_bill', 'fiscal_position', 'partner_flash']) | ||||||
|             return common_list |             return common_list | ||||||
|         elif self.env.context.get('sst_14', False): |         elif self.env.context.get('sst_14', False): | ||||||
|             common_list = ['firstname', 'lastname', 'midname', 'email', 'company_odoo_id', 'portal_id', 'opt_out'] |             common_list = ['firstname', 'lastname', 'midname', 'email', 'company_odoo_id', 'portal_id', 'opt_out'] | ||||||
|  |  | ||||||
|  | @ -65,6 +65,8 @@ class SaleOrder(models.Model): | ||||||
| #    pg9_call = fields.Char(string='PG9-Auftrag', compute='_pg9_call', store=False) | #    pg9_call = fields.Char(string='PG9-Auftrag', compute='_pg9_call', store=False) | ||||||
|     pg9_call_D = fields.Char(string='PG9-Auftrag_D', compute='_pg9_call', store=False) |     pg9_call_D = fields.Char(string='PG9-Auftrag_D', compute='_pg9_call', store=False) | ||||||
|     pg9_call_T = fields.Char(string='PG9-Auftrag_T', compute='_pg9_call', store=False) |     pg9_call_T = fields.Char(string='PG9-Auftrag_T', compute='_pg9_call', store=False) | ||||||
|  |     partner_flash = fields.Text(compute='_get_partner_flash', store=False) | ||||||
|  | #    partner_flash = fields.Char(store=False) | ||||||
| 
 | 
 | ||||||
|     @api.multi |     @api.multi | ||||||
|     def _reset_sequence(self): |     def _reset_sequence(self): | ||||||
|  | @ -87,10 +89,16 @@ class SaleOrder(models.Model): | ||||||
| 
 | 
 | ||||||
|     # end def _pg9_call |     # end def _pg9_call | ||||||
| 
 | 
 | ||||||
|  |     @api.multi | ||||||
|  |     def _get_partner_flash(self): | ||||||
|  |         for record in self: | ||||||
|  |             record.partner_flash = record.partner_id.partner_flash | ||||||
|  | 
 | ||||||
|     @api.multi |     @api.multi | ||||||
|     @api.onchange('partner_invoice_id') |     @api.onchange('partner_invoice_id') | ||||||
|     def _onchange_partner_invoice_id(self): |     def _onchange_partner_invoice_id(self): | ||||||
|         for record in self: |         for record in self: | ||||||
|  | #            record.partner_flash = record.partner_id.partner_flash | ||||||
|             if record.partner_invoice_id.is_retailer: |             if record.partner_invoice_id.is_retailer: | ||||||
|                 record.payment_term_id = record.partner_invoice_id.property_payment_term_id |                 record.payment_term_id = record.partner_invoice_id.property_payment_term_id | ||||||
| 
 | 
 | ||||||
|  | @ -452,6 +460,9 @@ class SaleOrder(models.Model): | ||||||
|     @api.multi |     @api.multi | ||||||
|     @api.onchange('partner_id') |     @api.onchange('partner_id') | ||||||
|     def onchange_partner_id(self): |     def onchange_partner_id(self): | ||||||
|  |         # for record in self: | ||||||
|  |         #     record.partner_flash = record.partner_id.partner_flash | ||||||
|  | 
 | ||||||
|         if not self.partner_id: |         if not self.partner_id: | ||||||
|             self.update({ |             self.update({ | ||||||
|                 'partner_invoice_id': False, |                 'partner_invoice_id': False, | ||||||
|  | @ -472,6 +483,10 @@ class SaleOrder(models.Model): | ||||||
| 
 | 
 | ||||||
|         if self.partner_id.team_id: |         if self.partner_id.team_id: | ||||||
|             values['team_id'] = self.partner_id.team_id.id |             values['team_id'] = self.partner_id.team_id.id | ||||||
|  | 
 | ||||||
|  |         if self.partner_id: | ||||||
|  |             values['partner_flash'] = self.partner_id.partner_flash | ||||||
|  | 
 | ||||||
|         self.update(values) |         self.update(values) | ||||||
| 
 | 
 | ||||||
|     @api.multi |     @api.multi | ||||||
|  | @ -504,6 +519,14 @@ class SaleOrderLine(models.Model): | ||||||
|     weight = fields.Float(string='Gewicht', compute='_compute_weight') |     weight = fields.Float(string='Gewicht', compute='_compute_weight') | ||||||
|     intrastat_id = fields.Many2one(comodel_name='report.intrastat.code', string='Intrastat Code') |     intrastat_id = fields.Many2one(comodel_name='report.intrastat.code', string='Intrastat Code') | ||||||
|     sequence = fields.Integer(string='Sequence', default=9999) |     sequence = fields.Integer(string='Sequence', default=9999) | ||||||
|  |     item_notes = fields.Text(string='Notes', related='lot_id.notes', store=False) | ||||||
|  |     item_warn = fields.Boolean(string='Notes!!!', compute='_compute_item_warn', store=False) | ||||||
|  | 
 | ||||||
|  |     @api.multi | ||||||
|  |     def _compute_item_warn(self): | ||||||
|  |         for record in self: | ||||||
|  |             iNote = str(record.lot_id.notes) | ||||||
|  |             record.item_warn = True if iNote.startswith('!') else False | ||||||
| 
 | 
 | ||||||
|     @api.multi |     @api.multi | ||||||
|     @api.onchange('product_id') |     @api.onchange('product_id') | ||||||
|  |  | ||||||
|  | @ -19,7 +19,9 @@ | ||||||
| # | # | ||||||
| ############################################################################## | ############################################################################## | ||||||
| 
 | 
 | ||||||
| from odoo import fields, models, api, tools | from odoo import fields, models, api, tools, _ | ||||||
|  | from odoo.exceptions import ValidationError | ||||||
|  | from odoo.tools.float_utils import float_compare, float_is_zero | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class StockProductionLot(models.Model): | class StockProductionLot(models.Model): | ||||||
|  | @ -60,3 +62,67 @@ class StockPicking(models.Model): | ||||||
| 
 | 
 | ||||||
|         res = lang_obj.format('%.' + str(2) + 'f', value, grouping=True, monetary=True) |         res = lang_obj.format('%.' + str(2) + 'f', value, grouping=True, monetary=True) | ||||||
|         return res |         return res | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class StockMove(models.Model): | ||||||
|  |     _inherit = "stock.move" | ||||||
|  | 
 | ||||||
|  |     manu_lots_visible = fields.Boolean(compute='_compute_manu_lots_visible') | ||||||
|  | 
 | ||||||
|  |     @api.model | ||||||
|  |     def create(self, vals): | ||||||
|  |         res = super(StockMove, self).create(vals) | ||||||
|  |         for move in res: | ||||||
|  |             move.update({'sequence': move.sale_line_id.sequence,}) | ||||||
|  |         return res | ||||||
|  | 
 | ||||||
|  |     @api.multi | ||||||
|  |     def _prepare_move_line_vals(self, quantity=None, reserved_quant=None): | ||||||
|  |         self.ensure_one() | ||||||
|  |         vals = super(StockMove, self)._prepare_move_line_vals(quantity=quantity, reserved_quant=reserved_quant) | ||||||
|  |         if self.sale_line_id.lot_id and not self.sale_line_id.product_id.can_be_sold_unconfigured: | ||||||
|  |             move_lot = self.sale_line_id.lot_id.id | ||||||
|  |             vals.update({'lot_id': move_lot,}) | ||||||
|  |         return vals | ||||||
|  | 
 | ||||||
|  |     def _compute_manu_lots_visible(self): | ||||||
|  |         for move_line in self: | ||||||
|  |             if not move_line.product_id.can_be_sold_unconfigured: | ||||||
|  |                 move_line.manu_lots_visible = True | ||||||
|  | 
 | ||||||
|  |     @api.multi | ||||||
|  |     def action_show_lot(self): | ||||||
|  |         self.ensure_one() | ||||||
|  |         action = self.env.ref('stock.action_production_lot_form').read()[0] | ||||||
|  |         action['res_id'] = self.move_line_ids.lot_id.id | ||||||
|  |         action['view_mode'] = 'form' | ||||||
|  |         action['views'] = [(False, 'form')] | ||||||
|  | 
 | ||||||
|  |         return action | ||||||
|  | 
 | ||||||
|  |     @api.depends('product_id', 'product_uom_qty', 'product_uom') | ||||||
|  |     def _cal_move_weight(self): | ||||||
|  |         for move in self: | ||||||
|  |             if move.sale_line_id.lot_id and not move.product_id.can_be_sold_unconfigured: | ||||||
|  |                 move.weight += (move.product_qty * move.sale_line_id.lot_id.weight) | ||||||
|  |             else: | ||||||
|  |                 move.weight += (move.product_qty * move.product_id.weight) | ||||||
|  | 
 | ||||||
|  | #        print(move.weight) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class StockQuant(models.Model): | ||||||
|  |     _inherit = "stock.quant" | ||||||
|  | 
 | ||||||
|  |     @api.constrains('quantity') | ||||||
|  |     def check_quantity(self): | ||||||
|  |         info = '' | ||||||
|  |         for quant in self: | ||||||
|  |             if float_compare(quant.quantity, 1, precision_rounding=quant.product_uom_id.rounding) > 0 and quant.lot_id and quant.product_id.tracking == 'serial': | ||||||
|  |                 smls = self.env['stock.move.line'].search([('lot_id', '=', quant.lot_id.id)]) | ||||||
|  |                 for sml in smls: | ||||||
|  |                     sm = self.env['stock.move'].search([('id', '=', sml.move_id.id)]) | ||||||
|  |                     info += '\n %s; %s; %s: %s' % (sm.origin,sm.reference,sm.sequence,quant.lot_id.name) | ||||||
|  | 
 | ||||||
|  |         if info: | ||||||
|  |             raise ValidationError(_('A serial number should only be linked to a single product.') + info) | ||||||
|  |  | ||||||
|  | @ -9,6 +9,8 @@ | ||||||
|                 <group> |                 <group> | ||||||
|                     <field name="name"/> |                     <field name="name"/> | ||||||
|                     <field name="print_default_code"/> |                     <field name="print_default_code"/> | ||||||
|  |                     <field name="print_sales_pic"/> | ||||||
|  |                     <field name="print_production_pic"/> | ||||||
|                 </group> |                 </group> | ||||||
|             </form> |             </form> | ||||||
|         </field> |         </field> | ||||||
|  | @ -21,6 +23,8 @@ | ||||||
|             <tree> |             <tree> | ||||||
|                 <field name="name"/> |                 <field name="name"/> | ||||||
|                 <field name="print_default_code"/> |                 <field name="print_default_code"/> | ||||||
|  |                 <field name="print_sales_pic"/> | ||||||
|  |                 <field name="print_production_pic"/> | ||||||
|             </tree> |             </tree> | ||||||
|         </field> |         </field> | ||||||
|     </record> |     </record> | ||||||
|  |  | ||||||
|  | @ -31,6 +31,9 @@ | ||||||
|             </xpath> |             </xpath> | ||||||
| 
 | 
 | ||||||
|             <xpath expr="//page[@name='internal_notes']" position="inside"> |             <xpath expr="//page[@name='internal_notes']" position="inside"> | ||||||
|  |                 <label for="partner_flash">Flash: </label> | ||||||
|  |                 <field name="partner_flash"/> | ||||||
|  |                 <div class="oe_clear"/> | ||||||
|                 <group name="general"> |                 <group name="general"> | ||||||
|                     <group name="portal_info" string="Portal Info"> |                     <group name="portal_info" string="Portal Info"> | ||||||
|                         <field name="info_kundennr"/> |                         <field name="info_kundennr"/> | ||||||
|  |  | ||||||
|  | @ -6,12 +6,20 @@ | ||||||
|         <field name="model">sale.order</field> |         <field name="model">sale.order</field> | ||||||
|         <field name="inherit_id" ref="sale.view_order_form"/> |         <field name="inherit_id" ref="sale.view_order_form"/> | ||||||
|         <field name="arch" type="xml"> |         <field name="arch" type="xml"> | ||||||
|  |             <tree position="attributes"> | ||||||
|  | <!--                <attribute name="decoration-info">item_notes</attribute> --> | ||||||
|  |                 <attribute name="decoration-bf">item_warn</attribute> | ||||||
|  |             </tree> | ||||||
|             <xpath expr="//sheet" position="before"> |             <xpath expr="//sheet" position="before"> | ||||||
|                 <header> |                 <header> | ||||||
|                     <button name="%(action_wizard_import_tzbox)d" string="TZBox-Datei importieren" type="action" class="oe_highlight oe_read_only" |                     <button name="%(action_wizard_import_tzbox)d" string="TZBox-Datei importieren" type="action" class="oe_highlight oe_read_only" | ||||||
|                             attrs="{'invisible':['|','|',('state','!=','draft'),('order_type','!=','T'),('assembly_state','not in',[False,'import_failed'])]}"/> |                             attrs="{'invisible':['|','|',('state','!=','draft'),('order_type','!=','T'),('assembly_state','not in',[False,'import_failed'])]}"/> | ||||||
|                 </header> |                 </header> | ||||||
|             </xpath> |             </xpath> | ||||||
|  |             <field name="partner_id" position="before"> | ||||||
|  |                 <field name="partner_flash" string="Flash: " class="oe_highlight" attrs="{'invisible':[('partner_flash','=',False)]}"/> | ||||||
|  |                 <div class="oe_clear"/> | ||||||
|  |             </field> | ||||||
|             <field name="client_order_ref" position="replace"/> |             <field name="client_order_ref" position="replace"/> | ||||||
|             <field name="origin" position="replace"/> |             <field name="origin" position="replace"/> | ||||||
|             <field name="payment_term_id" position="after"> |             <field name="payment_term_id" position="after"> | ||||||
|  | @ -66,9 +74,29 @@ | ||||||
|                 <field name="intrastat_id"/> |                 <field name="intrastat_id"/> | ||||||
|             </xpath> |             </xpath> | ||||||
|             <xpath expr="//field[@name='order_line']/tree//field[@name='product_id']" position="after"> |             <xpath expr="//field[@name='order_line']/tree//field[@name='product_id']" position="after"> | ||||||
|                 <field name="lot_id" options="{'no_open': True}"/> |                 <field name="item_notes" invisible="1"/> | ||||||
|  |                 <field name="item_warn" invisible="1"/> | ||||||
|  |                 <field name="lot_id" options='{"fg_color": "red:item_notes" }'/> | ||||||
|  | <!-- | ||||||
|  |                 <button name="action_show_lot" string="Lot" type="object" | ||||||
|  |                     icon="fa-list" | ||||||
|  |                     attrs="{'invisible': ['|',('lot_id', '=', False),('item_notes', '>', '')]}" options='{"warn": true}'/> | ||||||
|  |                 <button name="action_show_lot" string="Notes" type="object" | ||||||
|  |                     icon="fa-exclamation-triangle" | ||||||
|  |                     attrs="{'invisible': ['|','|',('lot_id', '=', False),('item_notes', '=', False),('item_notes', '=', '')]}" options='{"warn": true}'/> | ||||||
|  | --> | ||||||
|  |                 <button name="action_show_lot" string="Lot" type="object" | ||||||
|  |                     icon="fa-list" | ||||||
|  |                     attrs="{'invisible': ['|',('lot_id', '=', False),('item_warn','=',True)]}" options='{"warn": true}'/> | ||||||
|  |                 <button name="action_show_lot" string="Notes" type="object" | ||||||
|  |                     icon="fa-exclamation-triangle" | ||||||
|  |                     attrs="{'invisible': ['|',('lot_id', '=', False),('item_warn','=',False)]}" options='{"warn": true}'/> | ||||||
|  |                 <!--                        icon="{'fa-list': [('item_notes', '>', '')],'fa-exclamation-triangle': [('item_notes', '<', '')]}" --> | ||||||
|  | <!-- | ||||||
|                 <button name="action_show_lot" string="Lot" type="object" icon="fa-list" |                 <button name="action_show_lot" string="Lot" type="object" icon="fa-list" | ||||||
|                         attrs="{'invisible': [('lot_id', '=', False)]}" options='{"warn": true}'/> |                         attrs="{'invisible': [('lot_id', '=', False)]}" | ||||||
|  |                         options='{"warn": true}'/> | ||||||
|  | --> | ||||||
|                 <field name="from_designbox"/> |                 <field name="from_designbox"/> | ||||||
|             </xpath> |             </xpath> | ||||||
|             <xpath expr="//field[@name='order_line']/kanban//field[@name='product_id']" position="after"> |             <xpath expr="//field[@name='order_line']/kanban//field[@name='product_id']" position="after"> | ||||||
|  | @ -128,6 +156,7 @@ | ||||||
|         <field name="arch" type="xml"> |         <field name="arch" type="xml"> | ||||||
|             <field name="partner_id" position="after"> |             <field name="partner_id" position="after"> | ||||||
|                 <field name="partner_invoice_id"/> |                 <field name="partner_invoice_id"/> | ||||||
|  |                 <field name="partner_shipping_id" invisible="1"/> | ||||||
|             </field> |             </field> | ||||||
|             <field name="name" position="after"> |             <field name="name" position="after"> | ||||||
|                 <field name="order_type"/> |                 <field name="order_type"/> | ||||||
|  | @ -143,6 +172,7 @@ | ||||||
|         <field name="arch" type="xml"> |         <field name="arch" type="xml"> | ||||||
|             <field name="partner_id" position="after"> |             <field name="partner_id" position="after"> | ||||||
|                 <field name="partner_invoice_id"/> |                 <field name="partner_invoice_id"/> | ||||||
|  |                 <field name="partner_shipping_id" invisible="1"/> | ||||||
|             </field> |             </field> | ||||||
|             <field name="name" position="after"> |             <field name="name" position="after"> | ||||||
|                 <field name="order_type"/> |                 <field name="order_type"/> | ||||||
|  | @ -162,9 +192,19 @@ | ||||||
|             <field name="name" position="after"> |             <field name="name" position="after"> | ||||||
|                 <field name="client_order_ref"/> |                 <field name="client_order_ref"/> | ||||||
|                 <field name="origin"/> |                 <field name="origin"/> | ||||||
|                 <field name="assembly_state" string="PG Status"/> |                 <field name="confirmation_nr"/> | ||||||
|  |                 <field name="assembly_state"/> | ||||||
|                 <field name="order_type"/> |                 <field name="order_type"/> | ||||||
|             </field> |             </field> | ||||||
|  | <!-- | ||||||
|  |             <field name="partner_id" position="after"> | ||||||
|  |                 <field name="partner_shipping_id"/> | ||||||
|  |                 <field name="partner_invoice_id"/> | ||||||
|  |             </field> | ||||||
|  | --> | ||||||
|  |             <field name="partner_id" position="replace"> | ||||||
|  |                 <field name="partner_id"  string="Kunde" filter_domain="['|','|',('partner_id','ilike',self),('partner_shipping_id','ilike',self),('partner_invoice_id','ilike',self)]"/> | ||||||
|  |             </field> | ||||||
|             <filter name="customer" position="after"> |             <filter name="customer" position="after"> | ||||||
|                 <filter string="PG Status" domain="[]" context="{'group_by':'assembly_state'}"/> |                 <filter string="PG Status" domain="[]" context="{'group_by':'assembly_state'}"/> | ||||||
|                 <filter string="Rechnungsadresse" domain="[]" context="{'group_by':'partner_invoice_id'}"/> |                 <filter string="Rechnungsadresse" domain="[]" context="{'group_by':'partner_invoice_id'}"/> | ||||||
|  |  | ||||||
|  | @ -22,4 +22,17 @@ | ||||||
|         <field name="priority">0</field> |         <field name="priority">0</field> | ||||||
|     </record> |     </record> | ||||||
| 
 | 
 | ||||||
|  |     <record id="view_delivery_manu_lot" model="ir.ui.view"> | ||||||
|  |         <field name="name">view_delivery_manu_lot</field> | ||||||
|  |         <field name="model">stock.picking</field> | ||||||
|  |         <field name="inherit_id" ref="stock.view_picking_form"/> | ||||||
|  |         <field name="arch" type="xml"> | ||||||
|  |             <xpath expr="//field[@name='move_lines']/tree//field[@name='product_id']" position="after"> | ||||||
|  |                 <field name="manu_lots_visible" invisible="1"/> | ||||||
|  |                 <button name="action_show_lot" string="Lot for manufactoring parts" type="object" icon="fa-list" attrs="{'invisible': [('manu_lots_visible', '=', False)]}" options="{"warn": true}"/> | ||||||
|  |             </xpath> | ||||||
|  |         </field> | ||||||
|  |     </record> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| </odoo> | </odoo> | ||||||
|  |  | ||||||
|  | @ -45,8 +45,11 @@ | ||||||
|                     </p> |                     </p> | ||||||
|                     <p t-if="o._name == 'sale.order'"> |                     <p t-if="o._name == 'sale.order'"> | ||||||
|                         <t t-if="not (env.context.get('proforma', False) or is_pro_forma)"> |                         <t t-if="not (env.context.get('proforma', False) or is_pro_forma)"> | ||||||
|                             <span t-if="o.state not in ['draft','sent']">Auftragsbestätigung</span> | <!-- | ||||||
|                             <span t-if="o.state in ['draft','sent']">Angebot</span> | --> | ||||||
|  |                             <span t-if="not data.get('tz_report_production', False) and o.state not in ['draft','sent']">Auftragsbestätigung</span> | ||||||
|  |                             <span t-if="not data.get('tz_report_production', False) and o.state in ['draft','sent']">Angebot</span> | ||||||
|  |                             <span t-if="data.get('tz_report_production',False)">Produktionsschein</span> | ||||||
|                         </t> |                         </t> | ||||||
|                         <t t-if="env.context.get('proforma', False) or is_pro_forma"> |                         <t t-if="env.context.get('proforma', False) or is_pro_forma"> | ||||||
|                             <span>Proformarechnung</span> |                             <span>Proformarechnung</span> | ||||||
|  |  | ||||||
|  | @ -48,6 +48,7 @@ class AccountInvoiceLine(models.Model): | ||||||
|     ) |     ) | ||||||
| 
 | 
 | ||||||
|     lot_formatted_note = fields.Html( |     lot_formatted_note = fields.Html( | ||||||
|  |         comodel_name='stock.production.lot', | ||||||
|         string='Formatted Note', |         string='Formatted Note', | ||||||
|         compute='_compute_line_lots', |         compute='_compute_line_lots', | ||||||
|     ) |     ) | ||||||
|  | @ -57,9 +58,8 @@ class AccountInvoiceLine(models.Model): | ||||||
|         for line in self: |         for line in self: | ||||||
|             if not line.order_line_ids: |             if not line.order_line_ids: | ||||||
|                 return |                 return | ||||||
|             line.prod_lot_ids = self.mapped( |             line.prod_lot_ids = line.mapped( | ||||||
|                 'order_line_ids.move_ids.move_line_ids.lot_id') |                 'order_line_ids.move_ids.move_line_ids.lot_id') | ||||||
|         print('End') |  | ||||||
| 
 | 
 | ||||||
|     @api.multi |     @api.multi | ||||||
|     def _compute_line_lots(self): |     def _compute_line_lots(self): | ||||||
|  |  | ||||||
|  | @ -24,6 +24,11 @@ | ||||||
|                                 <span t-esc="o.partner_id.city"/> |                                 <span t-esc="o.partner_id.city"/> | ||||||
|                                 <br/> |                                 <br/> | ||||||
|                                 <span t-esc="o.partner_id.country_id.name"/> |                                 <span t-esc="o.partner_id.country_id.name"/> | ||||||
|  |                                 <br/> | ||||||
|  |                                 <div> | ||||||
|  |                                     <strong>Tel: </strong> | ||||||
|  |                                     <span t-esc="o.partner_id.phone"/> | ||||||
|  |                                 </div> | ||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-xs-3"> |                         <div class="col-xs-3"> | ||||||
|  | @ -41,6 +46,11 @@ | ||||||
|                                 <span t-esc="o.sale_id.partner_id.city"/> |                                 <span t-esc="o.sale_id.partner_id.city"/> | ||||||
|                                 <br/> |                                 <br/> | ||||||
|                                 <span t-esc="o.sale_id.partner_id.country_id.name"/> |                                 <span t-esc="o.sale_id.partner_id.country_id.name"/> | ||||||
|  |                                 <br/> | ||||||
|  |                                 <div> | ||||||
|  |                                     <strong>Tel: </strong> | ||||||
|  |                                     <span t-esc="o.sale_id.partner_id.phone"/> | ||||||
|  |                                 </div> | ||||||
|                             </div> |                             </div> | ||||||
|                         </div> |                         </div> | ||||||
|                         <div class="col-xs-3"> |                         <div class="col-xs-3"> | ||||||
|  | @ -101,6 +111,7 @@ | ||||||
|                                 <td t-if="o.origin"> |                                 <td t-if="o.origin"> | ||||||
|                                     <span t-field="o.origin"/> |                                     <span t-field="o.origin"/> | ||||||
|                                 </td> |                                 </td> | ||||||
|  | <!-- | ||||||
|                                 <td name="td_sched_date"> |                                 <td name="td_sched_date"> | ||||||
|                                     <t t-if="o.state == 'done'"> |                                     <t t-if="o.state == 'done'"> | ||||||
|                                         <span t-field="o.date_done"/> |                                         <span t-field="o.date_done"/> | ||||||
|  | @ -109,6 +120,10 @@ | ||||||
|                                         <span t-field="o.scheduled_date"/> |                                         <span t-field="o.scheduled_date"/> | ||||||
|                                     </t> |                                     </t> | ||||||
|                                 </td> |                                 </td> | ||||||
|  | --> | ||||||
|  |                                 <td name="td_sched_date"> | ||||||
|  |                                     <span t-field="o.scheduled_date" t-field-options='{"widget": "date"}'/> | ||||||
|  |                                 </td> | ||||||
|                                 <td t-if="o.picking_type_id.code == 'outgoing' and o.carrier_id"> |                                 <td t-if="o.picking_type_id.code == 'outgoing' and o.carrier_id"> | ||||||
|                                     <span t-field="o.carrier_id"/> |                                     <span t-field="o.carrier_id"/> | ||||||
|                                 </td> |                                 </td> | ||||||
|  | @ -161,10 +176,14 @@ | ||||||
|                                 <th> |                                 <th> | ||||||
|                                     <strong>Product</strong> |                                     <strong>Product</strong> | ||||||
|                                 </th> |                                 </th> | ||||||
|                                 <th name="lot_serial" t-if="has_serial_number"> | <!--                                <th name="lot_serial" t-if="has_serial_number"> --> | ||||||
|  |                                 <th class="text-center" name="lot_serial" t-if="has_serial_number and any([move_line.product_id.can_be_sold_unconfigured for move_line in o.move_line_ids])"> | ||||||
|                                     Lot/Serial Number |                                     Lot/Serial Number | ||||||
|                                 </th> |                                 </th> | ||||||
|                                 <th class="text-center"> |                                 <th class="text-center"> | ||||||
|  |                                     <strong>Weight</strong> | ||||||
|  |                                 </th> | ||||||
|  |                                 <th class="text-right"> | ||||||
|                                     <strong>Ordered Quantity</strong> |                                     <strong>Ordered Quantity</strong> | ||||||
|                                 </th> |                                 </th> | ||||||
|                                 <th t-if="any([move_line.state == 'done' for move_line in o.move_line_ids])" |                                 <th t-if="any([move_line.state == 'done' for move_line in o.move_line_ids])" | ||||||
|  | @ -193,18 +212,15 @@ | ||||||
|                                         <span t-field="move_line.package_id"/> |                                         <span t-field="move_line.package_id"/> | ||||||
|                                     </t> |                                     </t> | ||||||
|                                 </td> |                                 </td> | ||||||
|                                 <t t-if="has_serial_number"> |                                 <t  t-if="has_serial_number and any([move_line.product_id.can_be_sold_unconfigured for move_line in o.move_line_ids])"> | ||||||
|                                     <td> |                                     <td class="text-center"> | ||||||
|                                         <table width="100%"> |                                         <table width="100%"> | ||||||
|                                             <tr> |                                             <tr> | ||||||
|                                                 <td> |                                                 <td> | ||||||
|                                                     <span t-field="move_line.lot_id"/> |                                                     <span t-field="move_line.lot_id" t-if="move_line.product_id.can_be_sold_unconfigured"/> | ||||||
|                                                     <t t-if="not move_line.lot_id"> |  | ||||||
|                                                         <span t-field="move_line.lot_name"/> |  | ||||||
|                                                     </t> |  | ||||||
|                                                 </td> |                                                 </td> | ||||||
|                                                 <td name="lot_qty"> |                                                 <td name="lot_qty"> | ||||||
|                                                     <t t-if="move_line.product_qty"> |                                                     <t t-if="move_line.product_qty and move_line.product_id.can_be_sold_unconfigured"> | ||||||
|                                                         <span t-esc="o._formatLang(move_line.product_qty).strip('0').strip(',').strip('.')"/> |                                                         <span t-esc="o._formatLang(move_line.product_qty).strip('0').strip(',').strip('.')"/> | ||||||
|                                                     </t> |                                                     </t> | ||||||
|                                                 </td> |                                                 </td> | ||||||
|  | @ -213,6 +229,16 @@ | ||||||
|                                     </td> |                                     </td> | ||||||
|                                 </t> |                                 </t> | ||||||
|                                 <td class="text-center"> |                                 <td class="text-center"> | ||||||
|  |                                     <t t-if="not move_line.lot_id or move_line.product_id.can_be_sold_unconfigured"> | ||||||
|  |                                         <span t-esc="move_line.ordered_qty*move_line.product_id.weight"/> | ||||||
|  | <!--                                                        <span t-field="move_line.product_id.weight"/> --> | ||||||
|  |                                     </t> | ||||||
|  |                                     <t t-if="move_line.lot_id and not move_line.product_id.can_be_sold_unconfigured"> | ||||||
|  | <!--                                                        <t t-set="weight" t-value="move_line.ordered_qty*move_line.lot_id.weight"/> --> | ||||||
|  |                                         <span t-field="move_line.lot_id.weight"/> | ||||||
|  |                                     </t> | ||||||
|  |                                 </td> | ||||||
|  |                                 <td class="text-right"> | ||||||
|                                     <span t-field="move_line.package_id"/> |                                     <span t-field="move_line.package_id"/> | ||||||
|                                     <span t-if="move_line.package_id">:</span> |                                     <span t-if="move_line.package_id">:</span> | ||||||
| <!-- | <!-- | ||||||
|  |  | ||||||
|  | @ -0,0 +1,4 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | 
 | ||||||
|  | from . import models | ||||||
|  | #from . import wizards | ||||||
|  | @ -0,0 +1,26 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | 
 | ||||||
|  | # noinspection PyStatementEffect | ||||||
|  | { | ||||||
|  |     'name': 'TZ Report Production', | ||||||
|  |     'category': 'Custom', | ||||||
|  |     'version': '11.0.1.0.0', | ||||||
|  |     'summary': 'Print Report for Production (Description & Pictures)', | ||||||
|  |     'description': 'Print Report for Production (Description & Pictures)', | ||||||
|  |     'author': 'TZAustria', | ||||||
|  |     'website': 'https://www.tzaustria.at', | ||||||
|  |     'support': 'andreas.osim@glaser-co.at', | ||||||
|  |     'depends': [ | ||||||
|  |         'base', | ||||||
|  |         'sale', | ||||||
|  |         'dp_reports', | ||||||
|  |         'sale_management', | ||||||
|  |         'sale_comment_template', | ||||||
|  |         'dp_line_comment_template', | ||||||
|  |         ], | ||||||
|  |     'data': [ | ||||||
|  |         'reports/report_production.xml', | ||||||
|  |         ], | ||||||
|  |     'installable': True, | ||||||
|  |     'auto_install': False, | ||||||
|  | } | ||||||
|  | @ -0,0 +1,3 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | 
 | ||||||
|  | from . import report_helper | ||||||
|  | @ -0,0 +1,22 @@ | ||||||
|  | # -*- coding: utf-8 -*- | ||||||
|  | 
 | ||||||
|  | from odoo import api, models | ||||||
|  | 
 | ||||||
|  | class SaleOrder(models.AbstractModel): | ||||||
|  |     _name = 'report.tz_reports_production.report_production' | ||||||
|  |     _inherit = 'report.abstract_report' | ||||||
|  |     _template = 'tz_reports_production.report_production' | ||||||
|  | 
 | ||||||
|  |     @api.model | ||||||
|  |     def get_report_values(self, docids, data=None): | ||||||
|  |         model = 'sale.order' | ||||||
|  |         docs = self.env[model].browse(docids) | ||||||
|  |         data.update(tz_report_production=True) | ||||||
|  |         return { | ||||||
|  |             'doc_ids': docids, | ||||||
|  |             'doc_model': model, | ||||||
|  |             'docs': docs, | ||||||
|  |             'data': data, | ||||||
|  |             'field_set_in_lines': self._field_set_in_lines, | ||||||
|  |             'formatLang': self._formatLang, | ||||||
|  |         } | ||||||
|  | @ -0,0 +1,298 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | 
 | ||||||
|  | <odoo> | ||||||
|  |     <!-- Sale Order Body --> | ||||||
|  |     <template id="report_production_document"> | ||||||
|  |         <t t-call="web.external_layout"> | ||||||
|  |             <t t-set="o" t-value="o.with_context({'lang':o.partner_id.lang})"/> | ||||||
|  |             <div class="page"> | ||||||
|  |                 <div class="row"> | ||||||
|  |                     <div class="col-xs-3"> | ||||||
|  |                         <t t-call="dp_reports.partner_data"/> | ||||||
|  |                     </div> | ||||||
|  |                     <div class="col-xs-3"> | ||||||
|  |                         <strong>Lieferadresse</strong> | ||||||
|  |                         <div class="partner-data"> | ||||||
|  |                             <span t-esc="o.partner_shipping_id.name"/> | ||||||
|  |                             <br/> | ||||||
|  |                             <span t-esc="o.partner_shipping_id.street"/> | ||||||
|  |                             <br/> | ||||||
|  |                             <span t-esc="o.partner_shipping_id.zip"/> | ||||||
|  |                             <span t-esc="o.partner_shipping_id.city"/> | ||||||
|  |                             <br/> | ||||||
|  |                             <span t-esc="o.partner_shipping_id.country_id.name"/> | ||||||
|  |                         </div> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="row mt32"/> | ||||||
|  |                 <div class="row height-20"> | ||||||
|  |                     <div class="col-xs-3" style="padding-right: 4px"> | ||||||
|  |                         <strong> | ||||||
|  |                             <span class="col-xs-8" style="padding: 0px;width: 58%;">Kundennr.:</span> | ||||||
|  |                         </strong> | ||||||
|  |                         <span class="col-xs-4" style="padding: 0px;width: 42%;" t-field="o.partner_id.ref"/> | ||||||
|  |                     </div> | ||||||
|  |                     <strong> | ||||||
|  |                         <span class="col-xs-2">Ansprechpartner:</span> | ||||||
|  |                     </strong> | ||||||
|  |                     <span class="col-xs-3" t-field="o.user_id"/> | ||||||
|  |                     <strong> | ||||||
|  |                         <span class="col-xs-2">Positionen:</span> | ||||||
|  |                     </strong> | ||||||
|  |                     <span class="col-xs-2" t-field="o.positions"/> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="row height-20"> | ||||||
|  |                     <div class="col-xs-3" style="padding-right: 4px"> | ||||||
|  |                         <strong> | ||||||
|  |                             <span class="col-xs-8" style="padding: 0px;width: 58%;">Angebotsdatum:</span> | ||||||
|  |                         </strong> | ||||||
|  |                         <span class="col-xs-4" style="padding: 0px;width: 42%;" t-field="o.date_order" | ||||||
|  |                               t-options='{"widget": "date"}'/> | ||||||
|  |                     </div> | ||||||
|  |                     <strong> | ||||||
|  |                         <span class="col-xs-2">Email:</span> | ||||||
|  |                     </strong> | ||||||
|  |                     <span class="col-xs-3" t-field="res_company.email"/> | ||||||
|  |                     <p t-if="o.origin"> | ||||||
|  |                         <strong> | ||||||
|  |                             <span class="col-xs-2">Ref:</span> | ||||||
|  |                         </strong> | ||||||
|  |                         <span class="col-xs-2" t-field="o.origin"/> | ||||||
|  |                     </p> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="row"> | ||||||
|  |                     <div class="col-xs-3" style="padding-right: 4px"> | ||||||
|  |                         <strong> | ||||||
|  |                             <span class="col-xs-8" style="padding: 0px;width: 58%;">Lieferdatum:</span> | ||||||
|  |                         </strong> | ||||||
|  |                         <span class="col-xs-4" style="padding: 0px;width: 42%;" t-field="o.earliest_scheduled_date" | ||||||
|  |                               t-options='{"widget": "date"}'/> | ||||||
|  |                     </div> | ||||||
|  |                     <strong> | ||||||
|  |                         <span class="col-xs-2">Telefon:</span> | ||||||
|  |                     </strong> | ||||||
|  |                     <span class="col-xs-3" t-field="o.user_id.phone"/> | ||||||
|  |                     <strong> | ||||||
|  |                         <span class="col-xs-2">Bezeichnung:</span> | ||||||
|  |                     </strong> | ||||||
|  |                     <span class="col-xs-2" t-field="o.client_order_ref"/> | ||||||
|  |                 </div> | ||||||
|  |                 <div class="row mt32"/> | ||||||
|  |                 <p t-if="o.note1"> | ||||||
|  |                     <span t-field="o.note1"/> | ||||||
|  |                 </p> | ||||||
|  |                 <table class="table table-condensed" style="background-color: #E6E7E9;"> | ||||||
|  |                     <thead class="table-header"> | ||||||
|  |                         <tr> | ||||||
|  |                             <th class="text-center">Pos.</th> | ||||||
|  |                             <th class="text-right"/> | ||||||
|  |                             <th class="text-left">Artikel</th> | ||||||
|  | <!-- | ||||||
|  |                             <th class="text-right"/> | ||||||
|  |                             <th class="text-right">EP</th> | ||||||
|  |                             <th class="text-right" t-if="discount_is_set">Rabatt</th> | ||||||
|  |                             <th class="text-right">Gesamtpreis</th> | ||||||
|  | --> | ||||||
|  |                             <th class="text-right">Anzahl</th> | ||||||
|  |                             <th class="text-right">Gewicht</th> | ||||||
|  |                         </tr> | ||||||
|  |                     </thead> | ||||||
|  |                     <tbody class="sale-tbody"> | ||||||
|  |                         <t t-set="pos_nr" t-value="0"/> | ||||||
|  |                         <t t-foreach="o.order_line" t-as="order_line"> | ||||||
|  |                             <tr> | ||||||
|  |                                 <t t-set="pos_nr" t-value="pos_nr+1"/> | ||||||
|  |                                 <td class="text-center"> | ||||||
|  |                                     <span t-esc="pos_nr"/> | ||||||
|  |                                 </td> | ||||||
|  |                                 <td class="text-right"/> | ||||||
|  |                                 <td rowspan="2" class="text-left"> | ||||||
|  |                                     <t t-if="order_line.product_id.default_code and order_line.product_id.material_type_id.print_default_code"> | ||||||
|  |                                         <strong> | ||||||
|  |                                             <span t-field="order_line.product_id.default_code"/> | ||||||
|  |                                         </strong> | ||||||
|  |                                         <br/> | ||||||
|  |                                     </t> | ||||||
|  | <!-- | ||||||
|  |                                     <t t-if="order_line.intrastat_id"> | ||||||
|  |                                         <span> | ||||||
|  |                                             <strong>Zolltarif Nr.:</strong> | ||||||
|  |                                             <span t-field="order_line.intrastat_id"/> | ||||||
|  |                                         </span> | ||||||
|  |                                         <br/> | ||||||
|  |                                     </t> | ||||||
|  | --> | ||||||
|  |                                     <span t-field="order_line.name"/> | ||||||
|  | <!-- | ||||||
|  |                                     <t t-if="order_line.delivery_date and (order_line.delivery_date != o.delivery_date)"> | ||||||
|  |                                         <br/> | ||||||
|  |                                         <strong>Voraussichtliches Lieferdatum:</strong> | ||||||
|  |                                         <span t-field="order_line.delivery_date"/> | ||||||
|  |                                     </t> | ||||||
|  |                                     <p t-if="order_line.lot_id"> | ||||||
|  |                                         <span t-esc="order_line.lot_id.name.split('.')[2]"/> | ||||||
|  |                                     </p> | ||||||
|  | --> | ||||||
|  |                                     <p t-if="order_line.lot_id.notes"> | ||||||
|  |                                         <span t-field="order_line.lot_id.notes"/> | ||||||
|  |                                     </p> | ||||||
|  |                                     <p t-if="o.note_line"> | ||||||
|  |                                         <span t-field="o.note_line"/> | ||||||
|  |                                     </p> | ||||||
|  |                                 </td> | ||||||
|  |                                 <td class="text-right"> | ||||||
|  |                                     <t t-if="order_line.product_uom_qty"> | ||||||
|  |                                         <span t-esc="o._formatLang(order_line.product_uom_qty, False).strip('0').strip(',').strip('.')"/> | ||||||
|  |                                     </t> | ||||||
|  |                                 </td> | ||||||
|  |                                 <td class="text-right"> | ||||||
|  |                                     <t t-if="order_line.weight"> | ||||||
|  |                                         <span t-field="order_line.weight"/> | ||||||
|  |                                         kg | ||||||
|  |                                     </t> | ||||||
|  |                                 </td> | ||||||
|  | <!-- | ||||||
|  |                                 <td rowspan="2" class="text-right"> | ||||||
|  |                                     <span t-if="order_line.hide_discount" | ||||||
|  |                                           t-field="order_line.price_reduce"/> | ||||||
|  |                                     <span t-if="not order_line.hide_discount" | ||||||
|  |                                           t-field="order_line.price_unit"/> | ||||||
|  |                                 </td> | ||||||
|  | 
 | ||||||
|  |                                 <td rowspan="2" class="text-right" t-if="discount_is_set"> | ||||||
|  |                                     <t t-if="not order_line.hide_discount and order_line.discount"> | ||||||
|  |                                         <span t-esc="o._formatLang(order_line.discount, False).strip('0').strip(',').strip('.')"/> | ||||||
|  |                                         % | ||||||
|  |                                     </t> | ||||||
|  |                                 </td> | ||||||
|  |                                 <td rowspan="2" class="text-right"> | ||||||
|  |                                     <span t-field="order_line.price_subtotal"/> | ||||||
|  |                                 </td> | ||||||
|  | --> | ||||||
|  |                             </tr> | ||||||
|  |                             <tr> | ||||||
|  |                                 <td colspan="2" style="border: 0;text-align: center;"> | ||||||
|  |                                     <img t-if="order_line.lot_id.image_medium and order_line.product_id.material_type_id.print_production_pic" | ||||||
|  |                                          t-att-src="'data:image/png;base64,%s' % order_line.lot_id.image_medium.decode()" style="max-width: 128px;"/> | ||||||
|  |                                     <img t-if="not order_line.lot_id.image_medium and order_line.product_id.image_medium and order_line.product_id.material_type_id.print_production_pic" | ||||||
|  |                                          t-att-src="'data:image/png;base64,%s' % order_line.product_id.image_medium.decode()" style="max-width: 128px;"/> | ||||||
|  |                                 </td> | ||||||
|  |                             </tr> | ||||||
|  |                         </t> | ||||||
|  |                     </tbody> | ||||||
|  |                 </table> | ||||||
|  | 
 | ||||||
|  |                 <div class="row"> | ||||||
|  |                     <div class="col-xs-4 pull-right"> | ||||||
|  |                         <table class="table table-condensed"> | ||||||
|  |                             <tbody class="totals-tbody"> | ||||||
|  | <!-- | ||||||
|  |                                 <tr> | ||||||
|  |                                     <td> | ||||||
|  |                                         Nettobetrag | ||||||
|  |                                     </td> | ||||||
|  |                                     <td class="text-right"> | ||||||
|  |                                         <span t-field="o.amount_untaxed" | ||||||
|  |                                               t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> | ||||||
|  |                                     </td> | ||||||
|  |                                 </tr> | ||||||
|  |                                 <tr> | ||||||
|  |                                     <td> | ||||||
|  |                                         <span>USt.</span> | ||||||
|  |                                     </td> | ||||||
|  |                                     <td class="text-right"> | ||||||
|  |                                         <span t-field="o.amount_tax" | ||||||
|  |                                               t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> | ||||||
|  |                                     </td> | ||||||
|  |                                 </tr> | ||||||
|  |                                 <tr class="amount-total"> | ||||||
|  |                                     <td> | ||||||
|  |                                         <strong>Gesamtsumme</strong> | ||||||
|  |                                     </td> | ||||||
|  |                                     <td class="text-right"> | ||||||
|  |                                         <strong> | ||||||
|  |                                             <span t-field="o.amount_total" | ||||||
|  |                                                   t-options='{"widget": "monetary", "display_currency": o.currency_id}'/> | ||||||
|  |                                         </strong> | ||||||
|  |                                     </td> | ||||||
|  |                                 </tr> | ||||||
|  | --> | ||||||
|  |                             </tbody> | ||||||
|  |                         </table> | ||||||
|  |                     </div> | ||||||
|  |                 </div> | ||||||
|  | 
 | ||||||
|  |                 <p t-if="o.note2"> | ||||||
|  |                     <span t-field="o.note2"/> | ||||||
|  |                 </p> | ||||||
|  | 
 | ||||||
|  | <!-- | ||||||
|  |                 <div class="row"> | ||||||
|  |                     <p class="col-xs-12"> | ||||||
|  |                         <span t-field="o.note"/> | ||||||
|  |                     </p> | ||||||
|  |                     <p class="col-xs-12"> | ||||||
|  |                         Gesamtgewicht: | ||||||
|  |                         <span t-esc="round(o.weight_total, 2)"/> | ||||||
|  |                         kg | ||||||
|  |                         <br/> | ||||||
|  |                     </p> | ||||||
|  |                     <p class="col-xs-12" t-if="o.incoterm.name"> | ||||||
|  |                         Lieferkonditionen: | ||||||
|  |                         <span t-esc="o.incoterm.name"/> | ||||||
|  |                         <br/> | ||||||
|  |                     </p> | ||||||
|  |                     <p class="col-xs-12" t-if="o.payment_term_id and not o.partner_invoice_id.is_retailer"> | ||||||
|  |                         Zahlungskonditionen: | ||||||
|  |                         <span t-esc="o.payment_term_id.name"/> | ||||||
|  |                         <br/> | ||||||
|  |                     </p> | ||||||
|  |                     <p class="col-xs-12" t-if="o.state not in ['draft','sent']"> | ||||||
|  |                         Bitte prüfen Sie bei Anlieferung sofort die Verpackung bzw. Ware auf Beschädigung! | ||||||
|  |                         <br/> | ||||||
|  |                         Falls die beschädigte Ware angenommen wird, besteht kein Anspruch auf Kostenerstattung bzw. | ||||||
|  |                         Austausch. | ||||||
|  |                     </p> | ||||||
|  |                     <t t-if="o.state in ['draft','sent']"> | ||||||
|  |                         <p class="col-xs-12"> | ||||||
|  |                             Gültigkeit: 14 Tage ab Ausstellungsdatum | ||||||
|  |                         </p> | ||||||
|  |                         <p class="col-xs-12"> | ||||||
|  |                             Auftrag erteilt am: ____________________ | ||||||
|  |                         </p> | ||||||
|  |                         <p class="col-xs-12"> | ||||||
|  |                             Unterschrift: ____________________ | ||||||
|  |                         </p> | ||||||
|  |                     </t> | ||||||
|  |                 </div> | ||||||
|  | --> | ||||||
|  |             </div> | ||||||
|  |         </t> | ||||||
|  |     </template> | ||||||
|  | 
 | ||||||
|  |     <template id="tz_reports_production.report_production"> | ||||||
|  |         <t t-call="web.html_container"> | ||||||
|  |             <t t-foreach="docs" t-as="o"> | ||||||
|  |                 <t t-call="tz_reports_production.report_production_document" t-lang="o.partner_id.lang"/> | ||||||
|  |             </t> | ||||||
|  |         </t> | ||||||
|  |     </template> | ||||||
|  | 
 | ||||||
|  | <!-- | ||||||
|  |     <record id="tz_reports_production.action_report_production" model="ir.actions.report"> | ||||||
|  |     </record> | ||||||
|  | --> | ||||||
|  |     <report | ||||||
|  |             id="action_report_production" | ||||||
|  |             string="Produktionschein" | ||||||
|  |             model="sale.order" | ||||||
|  |             report_type="qweb-pdf" | ||||||
|  |             file="tz_reports_production.report_production" | ||||||
|  |             name="tz_reports_production.report_production" | ||||||
|  |             print_report_name="'Produktionsschein - %s' % (object.name)" | ||||||
|  |             paperformat="dp_reports.paperformat_a4_european" | ||||||
|  |     /> | ||||||
|  | 
 | ||||||
|  |                 <!-- print_report_name="(object.state in ('draft', 'sent') and 'Quotation - %s' % (object.name)) or 'Order - %s' % (object.name)" --> | ||||||
|  | 
 | ||||||
|  | </odoo> | ||||||
|  | @ -0,0 +1 @@ | ||||||
|  | "id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink" | ||||||
| 
 | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 17 KiB | 
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 361 KiB | 
|  | @ -0,0 +1,108 @@ | ||||||
|  | .. image:: https://img.shields.io/badge/license-LGPL--3-blue.svg | ||||||
|  |    :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html | ||||||
|  |    :alt: License: LGPL-3 | ||||||
|  | 
 | ||||||
|  | ============================ | ||||||
|  | Colorize field in tree views | ||||||
|  | ============================ | ||||||
|  | 
 | ||||||
|  | This module aims to add support for dynamically coloring fields in tree view | ||||||
|  | according to data in the record. | ||||||
|  | 
 | ||||||
|  | It provides attributes on fields with the similar syntax as the ``colors`` attribute | ||||||
|  | in tree tags. | ||||||
|  | 
 | ||||||
|  | Further, it provides a ``color_field`` attribute on tree tags's ``colors`` to use | ||||||
|  | a field's value as color. | ||||||
|  | 
 | ||||||
|  | Features | ||||||
|  | ======== | ||||||
|  | 
 | ||||||
|  | * Add attribute ``bg_color`` on field's ``options`` to color background of a cell in tree view | ||||||
|  | * Add attribute ``fg_color`` on field's ``options`` to change text color of a cell in tree view | ||||||
|  | * Add attribute ``color_field`` on the tree element's ``colors`` to use as color | ||||||
|  | 
 | ||||||
|  | Usage | ||||||
|  | ===== | ||||||
|  | 
 | ||||||
|  | * In the tree view declaration, put ``options='{"bg_color": "red: customer==True"}`` attribute in the ``field`` tag:: | ||||||
|  | 
 | ||||||
|  |     ... | ||||||
|  |     <field name="arch" type="xml"> | ||||||
|  |         <tree string="View name"> | ||||||
|  |             ... | ||||||
|  |             <field name="name" options='{"bg_color": "red: customer == True"}'/> | ||||||
|  |             ... | ||||||
|  |         </tree> | ||||||
|  |     </field> | ||||||
|  |     ... | ||||||
|  |      | ||||||
|  |     With this example, column which renders 'name' field will have its background colored in red. | ||||||
|  | 
 | ||||||
|  | * In the tree view declaration, put ``options='{"fg_color": "white:customer == True"}'`` attribute in the ``field`` tag:: | ||||||
|  | 
 | ||||||
|  |     ... | ||||||
|  |     <field name="arch" type="xml"> | ||||||
|  |         <tree string="View name"> | ||||||
|  |             ... | ||||||
|  |             <field name="name" options='{"fg_color": "white:customer == True"}'/> | ||||||
|  |             ... | ||||||
|  |         </tree> | ||||||
|  |     </field> | ||||||
|  |     ... | ||||||
|  |      | ||||||
|  |     With this example, column which renders 'name' field will have its text colored in white on a customer records. | ||||||
|  | 
 | ||||||
|  | * In the tree view declaration, use ``options='"color_field": "my_color"'`` attribute in the ``tree`` tag:: | ||||||
|  | 
 | ||||||
|  |     ... | ||||||
|  |     <field name="arch" type="xml"> | ||||||
|  |         <tree string="View name" colors="color_field: my_color" > | ||||||
|  |             ... | ||||||
|  |             <field name="my_color" invisible="1"/> | ||||||
|  |             ... | ||||||
|  |         </tree> | ||||||
|  |     </field> | ||||||
|  |     ... | ||||||
|  | 
 | ||||||
|  |     With this example, the content of the field named `my_color` will be used to | ||||||
|  |     populate the `my_color` CSS value. Use a function field to return whichever | ||||||
|  |     color you want depending on the other record values. Note that this | ||||||
|  |     overrides the rest of `colors` attributes, and that you need the tree | ||||||
|  |     to load your field in the first place by adding it as invisible field. | ||||||
|  | 
 | ||||||
|  | **Note that you should always use single quotes for fields' ``options`` and wrap nested values in double quotes since ``options`` is a JSON object.** | ||||||
|  | 
 | ||||||
|  | Bug Tracker | ||||||
|  | =========== | ||||||
|  | 
 | ||||||
|  | Bugs are tracked on `GitHub Issues | ||||||
|  | <https://github.com/OCA/web/issues>`_. In case of trouble, please | ||||||
|  | check there if your issue has already been reported. If you spotted it first, | ||||||
|  | help us smash it by providing a detailed and welcomed feedback. | ||||||
|  | 
 | ||||||
|  | Credits | ||||||
|  | ======= | ||||||
|  | 
 | ||||||
|  | Contributors | ||||||
|  | ------------ | ||||||
|  | 
 | ||||||
|  | * Damien Crier <damien.crier@camptocamp.com> | ||||||
|  | * Holger Brunn <hbrunn@therp.nl> | ||||||
|  | * Artem Kostyuk <a.kostyuk@mobilunity.com> | ||||||
|  | * Guewen Baconnier <guewen.baconnier@camptocamp.com> | ||||||
|  | 
 | ||||||
|  | Maintainer | ||||||
|  | ---------- | ||||||
|  | 
 | ||||||
|  | .. image:: https://odoo-community.org/logo.png | ||||||
|  |    :alt: Odoo Community Association | ||||||
|  |    :target: https://odoo-community.org | ||||||
|  | 
 | ||||||
|  | This module is maintained by the OCA. | ||||||
|  | 
 | ||||||
|  | OCA, or the Odoo Community Association, is a nonprofit organization whose | ||||||
|  | mission is to support the collaborative development of Odoo features and | ||||||
|  | promote its widespread use. | ||||||
|  | 
 | ||||||
|  | To contribute to this module, please visit https://odoo-community.org. | ||||||
|  | @ -0,0 +1,2 @@ | ||||||
|  | # Copyright 2015-2018 Camptocamp SA, Damien Crier | ||||||
|  | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||||||
|  | @ -0,0 +1,19 @@ | ||||||
|  | # Copyright 2015-2018 Camptocamp SA, Damien Crier | ||||||
|  | # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). | ||||||
|  | { | ||||||
|  |     'name': 'Colorize field in tree views', | ||||||
|  |     'summary': 'Allows you to dynamically color fields on tree views', | ||||||
|  |     'category': 'Hidden/Dependency', | ||||||
|  |     'version': '11.0.1.0.1', | ||||||
|  |     'depends': ['web'], | ||||||
|  |     'author': "Camptocamp, Therp BV, Odoo Community Association (OCA)", | ||||||
|  |     'license': 'AGPL-3', | ||||||
|  |     'website': 'https://github.com/OCA/web', | ||||||
|  |     'demo': [ | ||||||
|  |         "demo/res_users.xml", | ||||||
|  |     ], | ||||||
|  |     'data': [ | ||||||
|  |         'views/web_tree_dynamic_colored_field.xml', | ||||||
|  |     ], | ||||||
|  |     'installable': True, | ||||||
|  | } | ||||||
										
											Binary file not shown.
										
									
								
							| After Width: | Height: | Size: 9.2 KiB | 
|  | @ -0,0 +1,134 @@ | ||||||
|  | odoo.define('web_tree_dynamic_colored_field', function (require) { | ||||||
|  |     'use strict'; | ||||||
|  | 
 | ||||||
|  |     var ListRenderer = require('web.ListRenderer'); | ||||||
|  |     var pyeval = require('web.pyeval'); | ||||||
|  | 
 | ||||||
|  |     ListRenderer.include({ | ||||||
|  |         /** | ||||||
|  |          * Look up for a `color_field` parameter in tree `colors` attribute | ||||||
|  |          * | ||||||
|  |          * @override | ||||||
|  |          */ | ||||||
|  |         _renderBody: function () { | ||||||
|  |             if (this.arch.attrs.colors) { | ||||||
|  |                 var colorAttr = this.arch.attrs.colors.split(';') | ||||||
|  |                     .filter(color => color.trim().startsWith('color_field')); | ||||||
|  |                 if (colorAttr.length > 0) { | ||||||
|  |                     var colorField = colorAttr[0].split(':')[1].trim(); | ||||||
|  |                     // validate the presence of that field in tree view
 | ||||||
|  |                     var fieldNames = _(this.columns).map( | ||||||
|  |                         (value) => { return value.attrs.name; } | ||||||
|  |                     ); | ||||||
|  |                     if (fieldNames.indexOf(colorField) === -1) { | ||||||
|  |                         console.warn( | ||||||
|  |                             "No field named '" + colorField + "' present in view." | ||||||
|  |                         ); | ||||||
|  |                     } else { | ||||||
|  |                         this.colorField = colorField; | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return this._super(); | ||||||
|  |         }, | ||||||
|  |         /** | ||||||
|  |          * Colorize a cell during it's render | ||||||
|  |          * | ||||||
|  |          * @override | ||||||
|  |          */ | ||||||
|  |         _renderBodyCell: function (record, node, colIndex, options) { | ||||||
|  |             var $td = this._super.apply(this, arguments); | ||||||
|  |             var ctx = this.getEvalContext(record); | ||||||
|  |             this.applyColorize($td, record, node, ctx); | ||||||
|  |             return $td; | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Colorize the current cell depending on expressions provided. | ||||||
|  |          * | ||||||
|  |          * @param {Query Node} $td a <td> tag inside a table representing a list view | ||||||
|  |          * @param {Object} node an XML node (must be a <field>) | ||||||
|  |          */ | ||||||
|  |         applyColorize: function ($td, record, node, ctx) { | ||||||
|  |             // safely resolve value of `color_field` given in <tree>
 | ||||||
|  |             var treeColor = record.data[this.colorField]; | ||||||
|  |             if (treeColor) { | ||||||
|  |                 $td.css('color', treeColor); | ||||||
|  |             } | ||||||
|  |             // apply <field>'s own `options`
 | ||||||
|  |             if (!node.attrs.options) { return; } | ||||||
|  |             if (node.tag !== 'field') { return; } | ||||||
|  |             var nodeOptions = node.attrs.options; | ||||||
|  |             if (!_.isObject(nodeOptions)) { | ||||||
|  |                 nodeOptions = pyeval.py_eval(nodeOptions); | ||||||
|  |             } | ||||||
|  |             this.applyColorizeHelper($td, nodeOptions, node, 'fg_color', 'color', ctx); | ||||||
|  |             this.applyColorizeHelper($td, nodeOptions, node, 'bg_color', 'background-color', ctx); | ||||||
|  |         }, | ||||||
|  |         /** | ||||||
|  |          * @param {Object} nodeOptions a mapping of nodeOptions parameters to the color itself | ||||||
|  |          * @param {Object} node an XML node (must be a <field>) | ||||||
|  |          * @param {string} nodeAttribute an attribute of a node to apply a style onto | ||||||
|  |          * @param {string} cssAttribute a real CSS-compatible attribute | ||||||
|  |          */ | ||||||
|  |         applyColorizeHelper: function ($td, nodeOptions, node, nodeAttribute, cssAttribute, ctx) { | ||||||
|  |             if (nodeOptions[nodeAttribute]) { | ||||||
|  |                 var colors = _(nodeOptions[nodeAttribute].split(';')) | ||||||
|  |                     .chain() | ||||||
|  |                     .map(this.pairColors) | ||||||
|  |                     .value() | ||||||
|  |                     .filter(function CheckUndefined(value, index, ar) { | ||||||
|  |                         return value !== undefined; | ||||||
|  |                     }); | ||||||
|  |                 for (var i=0, len=colors.length; i<len; ++i) { | ||||||
|  |                     var pair = colors[i], | ||||||
|  |                         color = pair[0], | ||||||
|  |                         expression = pair[1]; | ||||||
|  |                     if (py.evaluate(expression, ctx).toJSON()) { | ||||||
|  |                         $td.css(cssAttribute, color); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  | 
 | ||||||
|  |         /** | ||||||
|  |          * Parse `<color>: <field> <operator> <value>` forms to | ||||||
|  |          * evaluatable expressions | ||||||
|  |          * | ||||||
|  |          * @param {string} pairColor `color: expression` pair | ||||||
|  |          */ | ||||||
|  |         pairColors: function (pairColor) { | ||||||
|  |             if (pairColor !== "") { | ||||||
|  |                 var pairList = pairColor.split(':'), | ||||||
|  |                     color = pairList[0], | ||||||
|  |                     // if one passes a bare color instead of an expression,
 | ||||||
|  |                     // then we consider that color is to be shown in any case
 | ||||||
|  |                     expression = pairList[1]? pairList[1] : 'True'; | ||||||
|  |                 return [color, py.parse(py.tokenize(expression)), expression]; | ||||||
|  |             } | ||||||
|  |             return undefined; | ||||||
|  |         }, | ||||||
|  |         /** | ||||||
|  |          * Construct domain evaluation context, mostly by passing | ||||||
|  |          * record's fields's values to local scope. | ||||||
|  |          * | ||||||
|  |          * @param {Object} record a record to build a context from | ||||||
|  |          */ | ||||||
|  |         getEvalContext: function (record) { | ||||||
|  |             var ctx = _.extend( | ||||||
|  |                 {}, | ||||||
|  |                 record.data, | ||||||
|  |                 pyeval.context() | ||||||
|  |             ); | ||||||
|  |             for (var key in ctx) { | ||||||
|  |                 var value = ctx[key]; | ||||||
|  |                 if (ctx[key] instanceof moment) { | ||||||
|  |                     // date/datetime fields are represented w/ Moment objects
 | ||||||
|  |                     // docs: https://momentjs.com/
 | ||||||
|  |                     ctx[key] = value.format('YYYY-MM-DD hh:mm:ss'); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             return ctx; | ||||||
|  |         } | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  | @ -0,0 +1,8 @@ | ||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <odoo> | ||||||
|  |     <template id="assets_backend" name="web_tree_dynamic_colored_field assets" inherit_id="web.assets_backend"> | ||||||
|  |         <xpath expr="." position="inside"> | ||||||
|  |             <script type="text/javascript" src="/web_tree_dynamic_colored_field/static/src/js/web_tree_dynamic_colored_field.js"></script> | ||||||
|  |         </xpath> | ||||||
|  |     </template> | ||||||
|  | </odoo> | ||||||
		Loading…
	
		Reference in New Issue