wip purchase_collective.
ToDo: Plantillas de correo, crear picking por supplier
This commit is contained in:
parent
d2ac963ee1
commit
4abeea64a5
13 changed files with 836 additions and 0 deletions
1
purchase_collective/__init__.py
Normal file
1
purchase_collective/__init__.py
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
from . import models
|
||||||
37
purchase_collective/__manifest__.py
Normal file
37
purchase_collective/__manifest__.py
Normal file
|
|
@ -0,0 +1,37 @@
|
||||||
|
{
|
||||||
|
'name': "Collective Purchases",
|
||||||
|
'summary': "Compras colectivas",
|
||||||
|
'description': """
|
||||||
|
Compras Colectivas
|
||||||
|
==================================================
|
||||||
|
Éste módulo permite a varios usuarios de Odoo realizar una compra de productos a un mismo proveedor que acepta pedidos conjuntos.
|
||||||
|
El Usuario que crea la orden es el encargado de distribuir los productos al resto de usuarios, cobrar de ellos y pagar al productor.
|
||||||
|
|
||||||
|
- modelo CollectivePurchases, con un campo que linka diferentes sales orders
|
||||||
|
- crea un único albarán de salida al proveedor con la suma de todas las sale orders
|
||||||
|
- cuando se recibe el cargamente del proveedor, una acción permite crear albaranes de entrega a los almacenes dde los nodo
|
||||||
|
--> ¿poner en un módulo aparte y quitar la dependencia a network_partner?
|
||||||
|
- nueva secuencia para collective order purchase
|
||||||
|
- workflow propio, por añadir los estados de entrega en subalmacén y entrega ala cliente.
|
||||||
|
- reglas de seguridad y grupos
|
||||||
|
""",
|
||||||
|
'author': "Criptomart",
|
||||||
|
'website': "https://criptomart.net",
|
||||||
|
'category': 'Purchase Management',
|
||||||
|
'version': '0.12.0.1.0',
|
||||||
|
'depends': ["purchase","sale","product","network_partner"],
|
||||||
|
'data': [
|
||||||
|
'security/purchase_collective_security.xml',
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
#'data/purchase_collective_workflow.xml',
|
||||||
|
#'data/purchase_collective_sequence.xml',
|
||||||
|
'views/purchase_collective.xml',
|
||||||
|
'views/sale_order.xml',
|
||||||
|
'views/actions.xml',
|
||||||
|
'views/menus.xml',
|
||||||
|
],
|
||||||
|
'demo': [],
|
||||||
|
'installable': True,
|
||||||
|
'auto_install': False,
|
||||||
|
'application': False,
|
||||||
|
}
|
||||||
17
purchase_collective/data/purchase_collective_sequence.xml
Normal file
17
purchase_collective/data/purchase_collective_sequence.xml
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="1">
|
||||||
|
<!-- Sequences for purchase.collective.order -->
|
||||||
|
<record id="seq_type_purchase_order" model="ir.sequence.type">
|
||||||
|
<field name="name">Collective Purchase Order</field>
|
||||||
|
<field name="code">purchase.collective.order</field>
|
||||||
|
</record>
|
||||||
|
<record id="seq_purchase_order" model="ir.sequence">
|
||||||
|
<field name="name">Collective Purchase Order</field>
|
||||||
|
<field name="code">purchase.collective.order</field>
|
||||||
|
<field name="prefix">CPO</field>
|
||||||
|
<field name="padding">5</field>
|
||||||
|
<field name="company_id" eval="False"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
240
purchase_collective/data/purchase_collective_workflow.xml
Normal file
240
purchase_collective/data/purchase_collective_workflow.xml
Normal file
|
|
@ -0,0 +1,240 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<record id="purchase_collective_order" model="workflow">
|
||||||
|
<field name="name">Collective Purchase Order Basic Workflow</field>
|
||||||
|
<field name="osv">purchase.collective.order</field>
|
||||||
|
<field name="on_create">True</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="act_draft" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="flow_start">True</field>
|
||||||
|
<field name="name">draft</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_sent" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">sent</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
<field name="action">write({'state':'sent'})</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_bid" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">bid</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
<field name="action">wkf_bid_received()</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_confirmed" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">confirmed</field>
|
||||||
|
<field name="split_mode">OR</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
<field name="action">wkf_confirm_order()</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_cancel" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">cancel</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
<field name="flow_stop">True</field>
|
||||||
|
<field name="action">wkf_action_cancel()</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_except_invoice" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">except_invoice</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
<field name="action">write({'state':'except_invoice'})</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_except_picking" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">except_picking</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
<field name="action">write({'state':'except_picking'})</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_router" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">router</field>
|
||||||
|
<field name="split_mode">OR</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
<field name="join_mode">AND</field>
|
||||||
|
<field name="action">wkf_approve_order()</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="act_invoice" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">invoice</field>
|
||||||
|
<field name="kind">subflow</field>
|
||||||
|
<field name="subflow_id" search="[('osv','=','account.invoice')]"/>
|
||||||
|
<field name="action">action_invoice_create()</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="act_invoice_done" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">invoice_done</field>
|
||||||
|
<field name="action">invoice_done()</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_invoice_end" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">invoice_end</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_picking" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">picking</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
<field name="action">action_picking_create()</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<record id="act_picking_done" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">picking_done</field>
|
||||||
|
<field name="action">picking_done()</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
</record>
|
||||||
|
<record id="act_done" model="workflow.activity">
|
||||||
|
<field name="wkf_id" ref="purchase_collective_order"/>
|
||||||
|
<field name="name">done</field>
|
||||||
|
<field name="action">wkf_po_done()</field>
|
||||||
|
<field name="kind">function</field>
|
||||||
|
<field name="flow_stop">True</field>
|
||||||
|
<field name="join_mode">AND</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="trans_draft_confirmed" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_draft"/>
|
||||||
|
<field name="act_to" ref="act_confirmed"/>
|
||||||
|
<field name="signal">purchase_confirm</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_draft_sent" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_draft"/>
|
||||||
|
<field name="act_to" ref="act_sent"/>
|
||||||
|
<field name="signal">send_rfq</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_bid_confirmed" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_bid"/>
|
||||||
|
<field name="act_to" ref="act_confirmed"/>
|
||||||
|
<field name="signal">purchase_confirm</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_sent_bid" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_sent"/>
|
||||||
|
<field name="act_to" ref="act_bid"/>
|
||||||
|
<field name="signal">bid_received</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_sent_cancel" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_sent"/>
|
||||||
|
<field name="act_to" ref="act_cancel"/>
|
||||||
|
<field name="signal">purchase_cancel</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_bid_cancel" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_bid"/>
|
||||||
|
<field name="act_to" ref="act_cancel"/>
|
||||||
|
<field name="signal">purchase_cancel</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="trans_confirmed_cancel" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_confirmed"/>
|
||||||
|
<field name="act_to" ref="act_cancel"/>
|
||||||
|
<field name="signal">purchase_cancel</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_draft_cancel" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_draft"/>
|
||||||
|
<field name="act_to" ref="act_cancel"/>
|
||||||
|
<field name="signal">purchase_cancel</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_confirmed_router" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_confirmed"/>
|
||||||
|
<field name="act_to" ref="act_router"/>
|
||||||
|
<!-- <field name="signal">purchase_approve</field> removed from simplification/useability -->
|
||||||
|
</record>
|
||||||
|
<record id="trans_router_picking" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_router"/>
|
||||||
|
<field name="act_to" ref="act_picking"/>
|
||||||
|
<field name="condition">has_stockable_product()</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_router_picking_done" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_router"/>
|
||||||
|
<field name="act_to" ref="act_picking_done"/>
|
||||||
|
<field name="condition">not has_stockable_product()</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="trans_router_invoice" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_router"/>
|
||||||
|
<field name="act_to" ref="act_invoice"/>
|
||||||
|
<field name="condition">invoice_method=='order'</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="trans_router_invoice_no_order" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_router"/>
|
||||||
|
<field name="act_to" ref="act_invoice_end"/>
|
||||||
|
<field name="condition">invoice_method<>'order'</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="trans_except_picking_picking_done" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_except_picking"/>
|
||||||
|
<field name="act_to" ref="act_picking_done"/>
|
||||||
|
<field name="signal">picking_ok</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_except_invoice_invoice_done" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_except_invoice"/>
|
||||||
|
<field name="act_to" ref="act_invoice_done"/>
|
||||||
|
<field name="signal">invoice_ok</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_except_picking" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_except_picking"/>
|
||||||
|
<field name="act_to" ref="act_cancel"/>
|
||||||
|
<field name="signal">purchase_cancel</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_except_invoice" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_except_invoice"/>
|
||||||
|
<field name="act_to" ref="act_cancel"/>
|
||||||
|
<field name="signal">purchase_cancel</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_picking_except_picking" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_picking"/>
|
||||||
|
<field name="act_to" ref="act_except_picking"/>
|
||||||
|
<field name="signal">picking_cancel</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="trans_invoice_except_invoice" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_invoice"/>
|
||||||
|
<field name="act_to" ref="act_except_invoice"/>
|
||||||
|
<field name="signal">subflow.cancel</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="trans_picking_picking_done" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_picking"/>
|
||||||
|
<field name="act_to" ref="act_picking_done"/>
|
||||||
|
<field name="signal">picking_done</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="trans_invoice_invoice_done" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_invoice"/>
|
||||||
|
<field name="act_to" ref="act_invoice_done"/>
|
||||||
|
<field name="signal">subflow.paid</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="trans_picking_done_done" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_picking_done"/>
|
||||||
|
<field name="act_to" ref="act_done"/>
|
||||||
|
</record>
|
||||||
|
<record id="trans_invoice_done_done" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_invoice_done"/>
|
||||||
|
<field name="act_to" ref="act_invoice_end"/>
|
||||||
|
</record>
|
||||||
|
<record id="trans_invoice_end_done" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_invoice_end"/>
|
||||||
|
<field name="act_to" ref="act_done"/>
|
||||||
|
<field name="condition">invoiced</field>
|
||||||
|
</record>
|
||||||
|
<record id="trans_invoice_end_cancel" model="workflow.transition">
|
||||||
|
<field name="act_from" ref="act_invoice_end"/>
|
||||||
|
<field name="act_to" ref="act_cancel"/>
|
||||||
|
<field name="signal">purchase_cancel</field>
|
||||||
|
<field name="condition">invoice_method<>'order'</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
||||||
3
purchase_collective/models/__init__.py
Normal file
3
purchase_collective/models/__init__.py
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
from . import purchase_collective
|
||||||
|
from . import sale_order
|
||||||
|
|
||||||
254
purchase_collective/models/purchase_collective.py
Normal file
254
purchase_collective/models/purchase_collective.py
Normal file
|
|
@ -0,0 +1,254 @@
|
||||||
|
import pytz
|
||||||
|
import logging
|
||||||
|
from datetime import datetime
|
||||||
|
from dateutil.relativedelta import relativedelta
|
||||||
|
from operator import attrgetter
|
||||||
|
|
||||||
|
from odoo import models, fields, api, osv, _
|
||||||
|
from odoo.exceptions import Warning
|
||||||
|
from odoo.tools.safe_eval import safe_eval as eval
|
||||||
|
import odoo.addons.decimal_precision as dp
|
||||||
|
|
||||||
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
class PurchaseCollectiveOrder(models.Model):
|
||||||
|
_name = 'purchase_collective.order'
|
||||||
|
_inherit = ['purchase.order']
|
||||||
|
_description = 'Collective Purchases'
|
||||||
|
|
||||||
|
sales_order_lines = fields.One2many('sale.order','cp_order_id','Collective Order Lines',states={'approved':[('readonly',True)],'done':[('readonly',True)]},copy=True )
|
||||||
|
deadline_date = fields.Date(string='Order Deadline', required=True, help="End date of the order. Place your orders before this date")
|
||||||
|
amount_untaxed = fields.Float('Amount untaxed')
|
||||||
|
amount_tax = fields.Float('Taxes')
|
||||||
|
amount_total = fields.Float('Amount Total')
|
||||||
|
wh_id = fields.Many2one('stock.warehouse',string="Almacén asociado",help="El almacén central de distribución.")
|
||||||
|
qty_min =fields.Float('Cantidad mínima del pedido', required=True, help='Cantidad mínima del pedido requerida para ejecutar la orden de compra')
|
||||||
|
|
||||||
|
#@api.onchange('sales_order_lines')
|
||||||
|
def onchange_order_line(self, args=None):
|
||||||
|
_logger.info("onchange_order_lines -- args: %s" %(args))
|
||||||
|
res = {
|
||||||
|
'amount_untaxed': 0.0,
|
||||||
|
'amount_tax': 0.0,
|
||||||
|
'amount_total': 0.0,
|
||||||
|
}
|
||||||
|
val = val1 = 0.0
|
||||||
|
order_list = self.sales_order_lines
|
||||||
|
#_logger.info("order %s " %order.id)
|
||||||
|
val_tax = 0.0
|
||||||
|
val_untax = 0.0
|
||||||
|
if order_list:
|
||||||
|
cur = self.pricelist_id.currency_id
|
||||||
|
for line in order.sales_order_lines:
|
||||||
|
if line.state in ['done','approved']:
|
||||||
|
val += line.amount_total
|
||||||
|
#val_tax += val.get('amount_tax',0.0)
|
||||||
|
#val_untax += val.get('amount_untaxed',0.0)
|
||||||
|
|
||||||
|
res['amount_tax'] = cur.round(val_tax)
|
||||||
|
res['amount_untaxed'] = val
|
||||||
|
res['amount_total']= val
|
||||||
|
|
||||||
|
#_logger.info("Res : %s " %res)
|
||||||
|
|
||||||
|
order.write({'amount_untaxed': res['amount_untaxed']})
|
||||||
|
order.write({'amount_tax': res['amount_tax']})
|
||||||
|
order.write({'amount_total': res['amount_total']})
|
||||||
|
_logger.info("res : %s" %(res))
|
||||||
|
_logger.warning("returning : %s" %res)
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def subscribe(self, partner):
|
||||||
|
self.message_subscribe(partner_ids=[(partner.id)])
|
||||||
|
self.message_post(body=("Order line created by %s" %(partner.name)))
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def button_details(self):
|
||||||
|
context = self.env.context.copy()
|
||||||
|
view_id = self.env.ref(
|
||||||
|
'sale.'
|
||||||
|
'view_order_form').id
|
||||||
|
|
||||||
|
context['default_is_cp'] = True
|
||||||
|
context['default_cp_order_id'] = self.id
|
||||||
|
context['supplier'] = self.partner_id
|
||||||
|
#context['default_partner_id'] = self.partner_id.id
|
||||||
|
context['default_pricelist_id'] = self.pricelist_id.id
|
||||||
|
context['default_order_date'] = self.date_order
|
||||||
|
context['default_date_planned'] = self.deadline_date
|
||||||
|
context['view_buttons'] = True
|
||||||
|
#context['fiscal_position'] = self.fiscal_position
|
||||||
|
#context['state'] = self.state
|
||||||
|
#context['parent'] = self.id
|
||||||
|
|
||||||
|
#partial_id = self.pool.get("purchase.collective.order.line").create(context=context)
|
||||||
|
|
||||||
|
view = {
|
||||||
|
'name': _('Details'),
|
||||||
|
'view_type': 'form',
|
||||||
|
'view_mode': 'form',
|
||||||
|
'res_model': 'sale.order',
|
||||||
|
'view_id': view_id,
|
||||||
|
'type': 'ir.actions.act_window',
|
||||||
|
'target': 'new',
|
||||||
|
'readonly': False,
|
||||||
|
#'res_id': partial_id,
|
||||||
|
'context': context
|
||||||
|
}
|
||||||
|
return view
|
||||||
|
|
||||||
|
def _get_order(self, ids):
|
||||||
|
result = {}
|
||||||
|
for line in self.pool.get('sale.order').browse(ids):
|
||||||
|
result[line.id] = True
|
||||||
|
return result.keys()
|
||||||
|
"""
|
||||||
|
def create(self, vals=None):
|
||||||
|
_logger.warning("Creating order %s" %(vals))
|
||||||
|
|
||||||
|
if vals.get('name','/')=='/':
|
||||||
|
vals['name'] = self.env['ir.sequence'].get('purchase_collective.order', context=context) or '/'
|
||||||
|
if not vals.get('location_id'):
|
||||||
|
for user_obj in self.env['res.users'].browse(uid, context=context):
|
||||||
|
vals['location_id'] = user_obj.partner_id.property_stock_supplier.id
|
||||||
|
#logging.info('adding location info %s' %vals.get('location_id'))
|
||||||
|
if not vals.get('pricelist_id'):
|
||||||
|
for user_obj in self.env['res.users'].browse(uid, context=context):
|
||||||
|
vals['pricelist_id'] = user_obj.partner_id.property_product_pricelist.id
|
||||||
|
#logging.info('adding pricelist %s' %vals.get('pricelist_id'))
|
||||||
|
order = super(PurchaseCollectiveOrder, self).create(vals)
|
||||||
|
return order
|
||||||
|
"""
|
||||||
|
|
||||||
|
def unlink(self, ids):
|
||||||
|
purchase_orders = self.read(ids, ['state'], context=context)
|
||||||
|
unlink_ids = []
|
||||||
|
for s in purchase_orders:
|
||||||
|
if s['state'] in ['draft','cancel']:
|
||||||
|
unlink_ids.append(s['id'])
|
||||||
|
else:
|
||||||
|
raise Warning(_('Invalid Action!'), _('In order to delete a purchase order, you must cancel it first.'))
|
||||||
|
|
||||||
|
# automatically sending subflow.delete upon deletion
|
||||||
|
self.signal_workflow(unlink_ids, 'purchase_cancel')
|
||||||
|
|
||||||
|
return super(PurchaseCollectiveOrder, self).unlink(unlink_ids, context=context)
|
||||||
|
|
||||||
|
def copy(self, id, default=None, context=None):
|
||||||
|
new_id = super(PurchaseCollectiveOrder, self).copy(id, default=default, context=context)
|
||||||
|
for po in self.browse([new_id], context=context):
|
||||||
|
for line in po.order_line:
|
||||||
|
vals = self.env['purchase_collective.order_line'].onchange_product_id(
|
||||||
|
line.id, po.pricelist_id.id, line.product_id.id, line.product_qty,
|
||||||
|
line.product_uom.id, po.partner_id.id, date_order=po.date_order, context=context
|
||||||
|
)
|
||||||
|
if vals.get('value', {}).get('date_planned'):
|
||||||
|
line.write({'date_planned': vals['value']['date_planned']})
|
||||||
|
return new_id
|
||||||
|
|
||||||
|
def set_order_line_status(self, ids, status, context=None):
|
||||||
|
"""
|
||||||
|
line = self.pool.get('purchase_collective.order_line')
|
||||||
|
order_line_ids = []
|
||||||
|
proc_obj = self.pool.get('procurement.order')
|
||||||
|
for order in self.browse(cr, uid, ids, context=context):
|
||||||
|
if status in ('draft', 'cancel'):
|
||||||
|
order_line_ids += [po_line.id for po_line in order.order_line]
|
||||||
|
else: # Do not change the status of already cancelled lines
|
||||||
|
order_line_ids += [po_line.id for po_line in order.order_line if po_line.state != 'cancel']
|
||||||
|
if order_line_ids:
|
||||||
|
line.write(cr, uid, order_line_ids, {'state': status}, context=context)
|
||||||
|
if order_line_ids and status == 'cancel':
|
||||||
|
procs = proc_obj.search(cr, uid, [('purchase_line_id', 'in', order_line_ids)], context=context)
|
||||||
|
if procs:
|
||||||
|
proc_obj.write(cr, uid, procs, {'state': 'exception'}, context=context)
|
||||||
|
"""
|
||||||
|
return True
|
||||||
|
|
||||||
|
def wkf_confirm_order(self, ids, context=None):
|
||||||
|
#_logger.info("Confirmando orden : %s" %ids)
|
||||||
|
todo = []
|
||||||
|
for po in self.browse(ids, context=context):
|
||||||
|
if not any(line.state != 'cancel' for line in po.order_line):
|
||||||
|
raise Warning(_('Error!'),_('You cannot confirm a purchase order without any purchase order line.'))
|
||||||
|
#if po.invoice_method == 'picking' and not any([l.product_id and l.product_id.type in ('product', 'consu') and l.state != 'cancel' for l in po.order_line]):
|
||||||
|
# raise osv.except_osv(
|
||||||
|
# _('Error!'),
|
||||||
|
# _("You cannot confirm a purchase order with Invoice Control Method 'Based on incoming shipments' that doesn't contain any stockable item."))
|
||||||
|
#for line in po.order_line:
|
||||||
|
# if line.state=='draft':
|
||||||
|
# todo.append(line.id)
|
||||||
|
#self.pool.get('purchase_collective.order_line').action_confirm(cr, uid, todo, context)
|
||||||
|
for id in ids:
|
||||||
|
self.write(id, {'state' : 'confirmed', 'validator' : uid}, context=context)
|
||||||
|
return True
|
||||||
|
|
||||||
|
def _set_po_lines_invoiced(self, ids, context=None):
|
||||||
|
"""
|
||||||
|
for po in self.browse(cr, uid, ids, context=context):
|
||||||
|
is_invoiced = []
|
||||||
|
if po.invoice_method == 'picking':
|
||||||
|
# We determine the invoiced state of the PO line based on the invoiced state
|
||||||
|
# of the associated moves. This should cover all possible cases:
|
||||||
|
# - all moves are done and invoiced
|
||||||
|
# - a PO line is split into multiple moves (e.g. if multiple pickings): some
|
||||||
|
# pickings are done, some are in progress, some are cancelled
|
||||||
|
for po_line in po.order_line:
|
||||||
|
if (po_line.move_ids and
|
||||||
|
all(move.state in ('done', 'cancel') for move in po_line.move_ids) and
|
||||||
|
not all(move.state == 'cancel' for move in po_line.move_ids) and
|
||||||
|
all(move.invoice_state == 'invoiced' for move in po_line.move_ids if move.state == 'done')
|
||||||
|
and po_line.invoice_lines and all(line.invoice_id.state not in ['draft', 'cancel'] for line in po_line.invoice_lines)):
|
||||||
|
is_invoiced.append(po_line.id)
|
||||||
|
elif po_line.product_id.type == 'service':
|
||||||
|
is_invoiced.append(po_line.id)
|
||||||
|
else:
|
||||||
|
for po_line in po.order_line:
|
||||||
|
if (po_line.invoice_lines and
|
||||||
|
all(line.invoice_id.state not in ['draft', 'cancel'] for line in po_line.invoice_lines)):
|
||||||
|
is_invoiced.append(po_line.id)
|
||||||
|
if is_invoiced:
|
||||||
|
self.pool['purchase_collective.order_line'].write(cr, uid, is_invoiced, {'invoiced': True})
|
||||||
|
workflow.trg_write(uid, 'purchase_colective.order', po.id, cr)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def action_picking_create(self, ids, context=None):
|
||||||
|
for order in self.browse(ids):
|
||||||
|
picking_vals = {
|
||||||
|
'picking_type_id': order.picking_type_id.id,
|
||||||
|
'partner_id': order.partner_id.id,
|
||||||
|
'date': order.date_order,
|
||||||
|
'origin': order.name
|
||||||
|
}
|
||||||
|
picking_id = self.env['stock.picking'].create(picking_vals, context=context)
|
||||||
|
# esta llamada da fallo
|
||||||
|
#self._create_stock_moves(cr, uid, order, order.order_line, picking_id, context=context)
|
||||||
|
return picking_id
|
||||||
|
|
||||||
|
# get the picking type for the warehouse defined in order
|
||||||
|
def _get_picking_in(self, context=None):
|
||||||
|
type_obj = self.env['stock.picking.type']
|
||||||
|
types = type_obj.search([('code', '=', 'incoming'),('warehouse_id.id','=',self.wh_id.id)], context=context)
|
||||||
|
if not types:
|
||||||
|
types = type_obj.search(cr, uid, [('code', '=', 'incoming'), ('warehouse_id', '=', False)], context=context)
|
||||||
|
if not types:
|
||||||
|
raise Warning(_('Error!'), _("Make sure you have defined the warehouse in the order!"))
|
||||||
|
#logging.info("Types %s" %types)
|
||||||
|
return types[0]
|
||||||
|
|
||||||
|
_defaults = {
|
||||||
|
'date_order': fields.datetime.now,
|
||||||
|
'state': 'draft',
|
||||||
|
'name': '/',
|
||||||
|
'shipped': 0,
|
||||||
|
'invoice_method': 'order',
|
||||||
|
'invoiced': 0,
|
||||||
|
'picking_type_id': _get_picking_in,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
16
purchase_collective/models/sale_order.py
Normal file
16
purchase_collective/models/sale_order.py
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
import random
|
||||||
|
|
||||||
|
from odoo import models, api, fields
|
||||||
|
|
||||||
|
|
||||||
|
class SaleOrder(models.Model):
|
||||||
|
_inherit = "sale.order"
|
||||||
|
|
||||||
|
cp_order_id = fields.Many2one(
|
||||||
|
'purchase_collective.order',
|
||||||
|
string='Parent Collective Purchase',
|
||||||
|
help='The collective purchase wich this order belongs',
|
||||||
|
ondelete='restrict'
|
||||||
|
)
|
||||||
|
is_cp = fields.Boolean(string="Is part of a Collective Purchase")
|
||||||
|
|
||||||
4
purchase_collective/security/ir.model.access.csv
Normal file
4
purchase_collective/security/ir.model.access.csv
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_purchase_collective_order_public,purchase_collective.order,model_purchase_collective_order,base.group_public,1,0,0,0
|
||||||
|
access_purchase_collective_order,purchase_collective.order,model_purchase_collective_order,group_purchase_collective_user,1,0,1,0
|
||||||
|
access_purchase_collective_order_manager,purchase_collective.order,model_purchase_collective_order,group_purchase_collective_manager,1,1,1,1
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<openerp>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<record model="ir.module.category" id="module_category_purchase_collective_management">
|
||||||
|
<field name="name">Collective Purchase</field>
|
||||||
|
<field name="description">Make bulk purchases from several users</field>
|
||||||
|
<field name="sequence">20</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="group_purchase_collective_user" model="res.groups">
|
||||||
|
<field name="name">User</field>
|
||||||
|
<field name="implied_ids" eval="[(4, ref('base.group_user')),(4,ref('purchase.group_purchase_user'))]"/>
|
||||||
|
<field name="category_id" ref="purchase_collective.module_category_purchase_collective_management"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="group_purchase_collective_manager" model="res.groups">
|
||||||
|
<field name="name">Manager</field>
|
||||||
|
<field name="category_id" ref="purchase_collective.module_category_purchase_collective_management"/>
|
||||||
|
<field name="implied_ids" eval="[(4, ref('group_purchase_collective_user')),(4,ref('purchase.group_purchase_manager'))]"/>
|
||||||
|
<field name="users" eval="[(4, ref('base.user_root'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.rule" id="purchase_collective_order_all_rule">
|
||||||
|
<field name="name">Collective Purchase Order All Read</field>
|
||||||
|
<field name="model_id" ref="model_purchase_collective_order"/>
|
||||||
|
<field name="global" eval="False"/>
|
||||||
|
<field name="groups" eval="[(4,ref('purchase_collective.group_purchase_collective_user'))]"/>
|
||||||
|
<field name="domain_force">['|',('company_id','=',False),('company_id','child_of',[user.company_id.parent_id.id])]</field>
|
||||||
|
<field name="perm_read" eval="True"/>
|
||||||
|
<field name="perm_write" eval="False"/>
|
||||||
|
<field name="perm_unlink" eval="False"/>
|
||||||
|
<field name="perm_create" eval="True"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record model="ir.rule" id="purchase_order_comp_rule">
|
||||||
|
<field name="name">Collective Purchase Order multi-company</field>
|
||||||
|
<field name="model_id" ref="model_purchase_collective_order"/>
|
||||||
|
<field name="global" eval="False"/>
|
||||||
|
<field name="domain_force">['|',('create_uid','=',False),('create_uid','=',user.id)]</field>
|
||||||
|
<field name="groups" eval="[(4,ref('purchase_collective.group_purchase_collective_user'))]"/>
|
||||||
|
<field name="perm_read" eval="True"/>
|
||||||
|
<field name="perm_write" eval="True"/>
|
||||||
|
<field name="perm_unlink" eval="False"/>
|
||||||
|
<field name="perm_create" eval="True"/>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</openerp>
|
||||||
56
purchase_collective/views/actions.xml
Normal file
56
purchase_collective/views/actions.xml
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
|
||||||
|
<record id="action_purchase_collective_order_open" model="ir.actions.act_window">
|
||||||
|
<field name="name">Open</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">purchase_collective.order</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="context">{
|
||||||
|
'search_default_my_sale_orders_filter': 1
|
||||||
|
}
|
||||||
|
</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="oe_view_nocontent_create">
|
||||||
|
Click to create a new Collective Purchase.
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_purchase_collective_order_confirmed" model="ir.actions.act_window">
|
||||||
|
<field name="name">Closed</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">purchase_collective.order</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="context">{
|
||||||
|
'search_default_my_sale_orders_filter': 1
|
||||||
|
}
|
||||||
|
</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="oe_view_nocontent_create">
|
||||||
|
Click to create a new Collective Purchase.
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_purchase_collective_order_cancel" model="ir.actions.act_window">
|
||||||
|
<field name="name">Cancelled</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">purchase_collective.order</field>
|
||||||
|
<field name="view_type">form</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
<field name="context">{
|
||||||
|
'search_default_my_sale_orders_filter': 1
|
||||||
|
}
|
||||||
|
</field>
|
||||||
|
<field name="help" type="html">
|
||||||
|
<p class="oe_view_nocontent_create">
|
||||||
|
Click to create a new Collective Purchase.
|
||||||
|
</p>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
31
purchase_collective/views/menus.xml
Normal file
31
purchase_collective/views/menus.xml
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
<odoo>
|
||||||
|
<data>
|
||||||
|
<!-- Top menu item -->
|
||||||
|
<menuitem
|
||||||
|
id="menu_collective_purchase_root"
|
||||||
|
name="Collective Purchases"
|
||||||
|
sequence="50"
|
||||||
|
/>
|
||||||
|
<!-- Submenu -->
|
||||||
|
<menuitem id="menu_purchase_collective_sub"
|
||||||
|
parent="purchase_collective.menu_collective_purchase_root"
|
||||||
|
name ="Collective Purchases"
|
||||||
|
sequence="5"
|
||||||
|
/>
|
||||||
|
<menuitem action="action_purchase_collective_order_open"
|
||||||
|
id="menu_purchase_collective_order_open"
|
||||||
|
parent="purchase_collective.menu_purchase_collective_sub"
|
||||||
|
sequence="10"
|
||||||
|
/>
|
||||||
|
<menuitem action="action_purchase_collective_order_confirmed"
|
||||||
|
id="menu_purchase_collective_order_confirmed"
|
||||||
|
parent="purchase_collective.menu_purchase_collective_sub"
|
||||||
|
sequence="20"
|
||||||
|
/>
|
||||||
|
<menuitem action="action_purchase_collective_order_cancel"
|
||||||
|
id="menu_purchase_collective_order_cancelled"
|
||||||
|
parent="purchase_collective.menu_purchase_collective_sub"
|
||||||
|
sequence="30"
|
||||||
|
/>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
111
purchase_collective/views/purchase_collective.xml
Normal file
111
purchase_collective/views/purchase_collective.xml
Normal file
|
|
@ -0,0 +1,111 @@
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="0">
|
||||||
|
|
||||||
|
<record id="purchase_collective_order_form_view" model="ir.ui.view">
|
||||||
|
<field name="name">purchase.collective.order.form.view</field>
|
||||||
|
<field name="model">purchase_collective.order</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Collective Purchase Order">
|
||||||
|
<header>
|
||||||
|
<button name="action_rfq_send" states="draft" string="Send by Email" type="object" context="{'send_rfq':True}" class="oe_highlight"/>
|
||||||
|
<button name="print_quotation" string="Print RFQ" type="object" states="draft" class="oe_highlight" groups="base.group_user"/>
|
||||||
|
<button name="button_confirm" type="object" states="sent" string="Confirm Order" class="oe_highlight" id="bid_confirm"/>
|
||||||
|
<button name="button_approve" type="object" states='to approve' string="Approve Order" class="oe_highlight" groups="purchase.group_purchase_manager"/>
|
||||||
|
<button name="action_view_invoice" string="Create Bill" type="object" class="oe_highlight" context="{'create_bill':True}" attrs="{'invisible': ['|', ('state', 'not in', ('purchase', 'done')), ('invoice_status', 'in', ('no', 'invoiced'))]}"/>
|
||||||
|
<button name="action_rfq_send" states="sent" string="Re-Send by Email" type="object" context="{'send_rfq':True}"/>
|
||||||
|
<button name="print_quotation" string="Print RFQ" type="object" states="sent" groups="base.group_user"/>
|
||||||
|
<button name="button_confirm" type="object" states="draft" string="Confirm Order" id="draft_confirm"/>
|
||||||
|
<button name="action_rfq_send" states="purchase" string="Send PO by Email" type="object" context="{'send_rfq':False}"/>
|
||||||
|
<button name="action_view_invoice" string="Create Bill" type="object" context="{'create_bill':True}" attrs="{'invisible': ['|', ('state', 'not in', ('purchase', 'done')), ('invoice_status', 'not in', ('no', 'invoiced'))]}"/>
|
||||||
|
<button name="button_draft" states="cancel" string="Set to Draft" type="object" />
|
||||||
|
<button name="button_cancel" states="draft,to approve,sent,purchase" string="Cancel" type="object" />
|
||||||
|
<button name="button_done" type="object" string="Lock" states="purchase"/>
|
||||||
|
<button name="button_unlock" type="object" string="Unlock" states="done" groups="purchase.group_purchase_manager"/>
|
||||||
|
<field name="state" widget="statusbar" statusbar_visible="draft,sent,purchase" readonly="1"/>
|
||||||
|
</header>
|
||||||
|
<sheet>
|
||||||
|
<div class="oe_button_box" name="button_box">
|
||||||
|
<button type="object" name="action_view_invoice"
|
||||||
|
class="oe_stat_button"
|
||||||
|
icon="fa-pencil-square-o" attrs="{'invisible':['|', ('invoice_count', '=', 0), ('state', 'in', ('draft','sent','to approve'))]}">
|
||||||
|
<field name="invoice_count" widget="statinfo" string="Vendor Bills"/>
|
||||||
|
<field name='invoice_ids' invisible="1"/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="oe_title">
|
||||||
|
<span class="o_form_label" attrs="{'invisible': [('state','not in',('draft','sent'))]}">Request for Quotation </span>
|
||||||
|
<span class="o_form_label" attrs="{'invisible': [('state','in',('draft','sent'))]}">Purchase Order </span>
|
||||||
|
<h1>
|
||||||
|
<field name="name" readonly="1"/>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="partner_id" widget="res_partner_many2one" context="{'search_default_supplier':1, 'default_supplier':1, 'default_customer':0, 'show_vat': True}" domain="[('supplier','=',True)]"
|
||||||
|
placeholder="Name, TIN, Email, or Reference"
|
||||||
|
/>
|
||||||
|
<field name="partner_ref"/>
|
||||||
|
<field name="currency_id" groups="base.group_multi_currency" force_save="1"/>
|
||||||
|
<field name="deadline_date" attrs="{'required': True}" />
|
||||||
|
<field name="qty_min" attrs="{'required': True }" />
|
||||||
|
<field name="wh_id"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="date_order"/>
|
||||||
|
<field name="origin" attrs="{'invisible': [('origin','=',False)]}"/>
|
||||||
|
<field name="company_id" groups="base.group_multi_company" options="{'no_create': True}"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
<notebook>
|
||||||
|
<page string="Pedidos de ventas">
|
||||||
|
<field name="sales_order_lines">
|
||||||
|
<tree string="Collective Purchase Order Lines" editable="bottom">
|
||||||
|
<field name="name"/>
|
||||||
|
<field name="partner_id" string="Customer"/>
|
||||||
|
<field name="state" invisible='0'/>
|
||||||
|
<field name="amount_total"/>
|
||||||
|
<!--
|
||||||
|
<button name="button_manual_payment" string="Manual Payment" type="object"
|
||||||
|
context="{'purchase_collective_line' : True, 'order_line_id': id, 'create_uid' : create_uid}"
|
||||||
|
states="draft"
|
||||||
|
/>
|
||||||
|
-->
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</page>
|
||||||
|
<page string="Other Information" name="purchase_delivery_invoice">
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<label for="date_planned"/>
|
||||||
|
<div>
|
||||||
|
<!-- Expected to be readonly at creation otherwise recompute will change the value anyway -->
|
||||||
|
<field name="date_planned" attrs="{'readonly': ['|', ('id', '=', False), ('state', 'not in', ('draft', 'sent'))]}"/>
|
||||||
|
<button name="action_set_date_planned" type="object"
|
||||||
|
states="draft,sent"
|
||||||
|
string="Set date to all order lines"
|
||||||
|
help="This changes the scheduled date of all order lines to the given date"
|
||||||
|
class="fa fa-calendar o_icon_button oe_edit_only"/>
|
||||||
|
</div>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="user_id"/>
|
||||||
|
<field name="invoice_status"/>
|
||||||
|
<field name="payment_term_id" options="{'no_open': True, 'no_create': True}" attrs="{'readonly': ['|', ('invoice_status','=', 'invoiced'), ('state', '=', 'done')]}"/>
|
||||||
|
<field name="fiscal_position_id" options="{'no_create': True}" attrs="{'readonly': ['|', ('invoice_status','=', 'invoiced'), ('state', '=', 'done')]}"/>
|
||||||
|
<field name="date_approve" groups="base.group_no_one"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</page>
|
||||||
|
</notebook>
|
||||||
|
</sheet>
|
||||||
|
<div class="oe_chatter">
|
||||||
|
<field name="message_follower_ids" widget="mail_followers"/>
|
||||||
|
<field name="activity_ids" widget="mail_activity"/>
|
||||||
|
<field name="message_ids" widget="mail_thread"/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
|
|
||||||
18
purchase_collective/views/sale_order.xml
Normal file
18
purchase_collective/views/sale_order.xml
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="0">
|
||||||
|
<record id="view_form_sale_order_cp" model="ir.ui.view">
|
||||||
|
<field name="name">sale order collective purchase extension</field>
|
||||||
|
<field name="model">sale.order</field>
|
||||||
|
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<field name="partner_id" position="before" >
|
||||||
|
<group>
|
||||||
|
<field name="is_cp" string="Is Collective Purchase" help="Is part o a collective Purchase" groups="purchase_collective.group_purchase_collective_manager"/>
|
||||||
|
<field name="cp_order_id" string="Collective Purchase wich this order belogns" groups="purchase_collective.group_purchase_collective_manager"/>
|
||||||
|
</group>
|
||||||
|
</field>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
Loading…
Add table
Add a link
Reference in a new issue