mirror of
https://gitlab.com/sonalarora/tra_backend.git
synced 2025-12-17 18:29:08 +02:00
add 2 mayur modules
This commit is contained in:
3
MKS_Tradex_Backend_2/__init__.py
Executable file
3
MKS_Tradex_Backend_2/__init__.py
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import models
|
||||||
29
MKS_Tradex_Backend_2/__manifest__.py
Executable file
29
MKS_Tradex_Backend_2/__manifest__.py
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
{
|
||||||
|
'name': 'MKS Tradex Backend',
|
||||||
|
'version': '13.0.1.0',
|
||||||
|
'category': 'Operations/Purchase',
|
||||||
|
'description': """
|
||||||
|
This module allows you to manage your Purchase Agreements flow.
|
||||||
|
Store keeper create Purchase Agreement
|
||||||
|
Purchase Codinator Approve / Reject Purchase Agreement
|
||||||
|
Purchase Manager Approve / Reject Purchase Agreement
|
||||||
|
Purchase Codinator Create RFQ after Approve purchase agreement by purchase manager
|
||||||
|
|
||||||
|
""",
|
||||||
|
'depends': ['purchase','purchase_requisition','sale_management'],
|
||||||
|
'data': [
|
||||||
|
'edi/mail_template.xml',
|
||||||
|
'edi/purchase_mail_template.xml',
|
||||||
|
'edi/sale_mail_template.xml',
|
||||||
|
'edi/invoice_mail_template.xml',
|
||||||
|
'security/purchase_security.xml',
|
||||||
|
'security/account_security.xml',
|
||||||
|
'views/purchase_requisition_views.xml',
|
||||||
|
'views/purchase_order_views.xml',
|
||||||
|
'views/sale_order_view.xml',
|
||||||
|
'views/stock_picking.xml',
|
||||||
|
'views/account_move_views.xml',
|
||||||
|
],
|
||||||
|
|
||||||
|
}
|
||||||
36
MKS_Tradex_Backend_2/edi/invoice_mail_template.xml
Executable file
36
MKS_Tradex_Backend_2/edi/invoice_mail_template.xml
Executable file
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<!--Email template manager request template -->
|
||||||
|
|
||||||
|
|
||||||
|
<record id="invoice_approval_mail_template" model="mail.template">
|
||||||
|
<field name="name">Invoice Approval Email Temmplate</field>
|
||||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.company_id.name, object.user_id.email) or '')|safe}</field>
|
||||||
|
<field name="subject">Invoice Financial Approval</field>
|
||||||
|
<field name="model_id" ref="account.model_account_move"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
|
||||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px; color: rgb(34, 34, 34); background-color: #FFF;">
|
||||||
|
<p>To Manager,</p> <br/>
|
||||||
|
<p>Please Approve Account Invoice Request bellow link </b> </p>
|
||||||
|
|
||||||
|
|
||||||
|
% set setup_url = object.make_invoice_url()
|
||||||
|
<br/><br/>
|
||||||
|
<a href="${setup_url}" style="background-color: #1abc9c;padding: 20px;text-decoration: none;color: #fff;border-radius: 5px;font-size: 16px;" class="o_default_snippet_text">Approve Invoice Request</a>
|
||||||
|
<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
66
MKS_Tradex_Backend_2/edi/mail_template.xml
Executable file
66
MKS_Tradex_Backend_2/edi/mail_template.xml
Executable file
@@ -0,0 +1,66 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<!--Email template manager request template -->
|
||||||
|
|
||||||
|
|
||||||
|
<record id="purchase_coordinator_template" model="mail.template">
|
||||||
|
<field name="name">Purchase Coordinator</field>
|
||||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.company_id.name, object.user_id.email) or '')|safe}</field>
|
||||||
|
<field name="subject">Purchase Agreements Approve</field>
|
||||||
|
<field name="model_id" ref="purchase_requisition.model_purchase_requisition"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
|
||||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px; color: rgb(34, 34, 34); background-color: #FFF;">
|
||||||
|
<p>Dear Purchase Coordinator,</p> <br/>
|
||||||
|
<p>Please Approve Purchase Agreements bellow link </b> </p>
|
||||||
|
|
||||||
|
${object.basick_information() | safe}
|
||||||
|
${object.line_information() | safe}
|
||||||
|
|
||||||
|
% set setup_url = object.make_url()
|
||||||
|
<br/><br/>
|
||||||
|
<a href="${setup_url}" style="background-color: #1abc9c;padding: 20px;text-decoration: none;color: #fff;border-radius: 5px;font-size: 16px;" class="o_default_snippet_text">Approve Purchase Agreements</a>
|
||||||
|
<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="purchase_manager_template" model="mail.template">
|
||||||
|
<field name="name">Purchase Manager</field>
|
||||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.company_id.name, object.user_id.email) or '')|safe}</field>
|
||||||
|
<field name="subject">Purchase Agreements Approve</field>
|
||||||
|
<field name="model_id" ref="purchase_requisition.model_purchase_requisition"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
|
||||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px; color: rgb(34, 34, 34); background-color: #FFF;">
|
||||||
|
<p>Dear Managment,</p><br/>
|
||||||
|
<p>Please Approve Purchase Agreements bellow link </b> </p>
|
||||||
|
|
||||||
|
${object.basick_information() | safe}
|
||||||
|
${object.line_information() | safe}
|
||||||
|
|
||||||
|
|
||||||
|
% set setup_url = object.make_url()
|
||||||
|
<br/><br/>
|
||||||
|
<a href="${setup_url}" style="background-color: #1abc9c;padding: 20px;text-decoration: none;color: #fff;border-radius: 5px;font-size: 16px;" class="o_default_snippet_text">Approve Purchase Agreements</a>
|
||||||
|
<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
57
MKS_Tradex_Backend_2/edi/purchase_mail_template.xml
Executable file
57
MKS_Tradex_Backend_2/edi/purchase_mail_template.xml
Executable file
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<!--Email template manager request template -->
|
||||||
|
|
||||||
|
|
||||||
|
<record id="purchase_req_coordinator_template" model="mail.template">
|
||||||
|
<field name="name">Purchase Coordinator</field>
|
||||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.company_id.name, object.user_id.email) or '')|safe}</field>
|
||||||
|
<field name="subject">Purchase Request Approve</field>
|
||||||
|
<field name="model_id" ref="purchase.model_purchase_order"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
|
||||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px; color: rgb(34, 34, 34); background-color: #FFF;">
|
||||||
|
<p>Dear Coordinator,</p> <br/>
|
||||||
|
<p>Please Approve Purchase Request bellow link </b> </p>
|
||||||
|
|
||||||
|
|
||||||
|
% set setup_url = object.make_url()
|
||||||
|
<br/><br/>
|
||||||
|
<a href="${setup_url}" style="background-color: #1abc9c;padding: 20px;text-decoration: none;color: #fff;border-radius: 5px;font-size: 16px;" class="o_default_snippet_text">Approve Purchase Request</a>
|
||||||
|
<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="purchase_req_manager_template" model="mail.template">
|
||||||
|
<field name="name">Purchase Manager</field>
|
||||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.company_id.name, object.user_id.email) or '')|safe}</field>
|
||||||
|
<field name="subject">Purchase Request confirm</field>
|
||||||
|
<field name="model_id" ref="purchase.model_purchase_order"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
|
||||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px; color: rgb(34, 34, 34); background-color: #FFF;">
|
||||||
|
<p>Dear Manager,</p> <br/>
|
||||||
|
<p>Please Confirm Purchase Request bellow link </b> </p>
|
||||||
|
|
||||||
|
|
||||||
|
% set setup_url = object.make_url()
|
||||||
|
<br/><br/>
|
||||||
|
<a href="${setup_url}" style="background-color: #1abc9c;padding: 20px;text-decoration: none;color: #fff;border-radius: 5px;font-size: 16px;" class="o_default_snippet_text">Approve Purchase Request</a>
|
||||||
|
<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
</odoo>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
101
MKS_Tradex_Backend_2/edi/sale_mail_template.xml
Executable file
101
MKS_Tradex_Backend_2/edi/sale_mail_template.xml
Executable file
@@ -0,0 +1,101 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<odoo>
|
||||||
|
<!--Email template manager request template -->
|
||||||
|
|
||||||
|
|
||||||
|
<record id="sale_manager_template" model="mail.template">
|
||||||
|
<field name="name">Sale Manager</field>
|
||||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.company_id.name, object.user_id.email) or '')|safe}</field>
|
||||||
|
<field name="subject">Sale Management Approval</field>
|
||||||
|
<field name="model_id" ref="sale.model_sale_order"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
|
||||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px; color: rgb(34, 34, 34); background-color: #FFF;">
|
||||||
|
<p>Dear Sale Management ,</p> <br/>
|
||||||
|
<p>Please Approve RFQ Request bellow link </b> </p>
|
||||||
|
|
||||||
|
|
||||||
|
% set setup_url = object.make_url()
|
||||||
|
<br/><br/>
|
||||||
|
<a href="${setup_url}" style="background-color: #1abc9c;padding: 20px;text-decoration: none;color: #fff;border-radius: 5px;font-size: 16px;" class="o_default_snippet_text">Approve Sale Order Request</a>
|
||||||
|
<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="sale_user_template" model="mail.template">
|
||||||
|
<field name="name">Sale Store Keeper</field>
|
||||||
|
<field name="subject">Management Approval</field>
|
||||||
|
<field name="model_id" ref="sale.model_sale_order"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
|
||||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px; color: rgb(34, 34, 34); background-color: #FFF;">
|
||||||
|
<p>Dear ${(object.user_id.name)} ,</p> <br/>
|
||||||
|
<p>Please Approve RFQ Request bellow link </b> </p>
|
||||||
|
|
||||||
|
% set setup_url = object.make_url()
|
||||||
|
<br/><br/>
|
||||||
|
<a href="${setup_url}" style="background-color: #1abc9c;padding: 20px;text-decoration: none;color: #fff;border-radius: 5px;font-size: 16px;" class="o_default_snippet_text">Approve Sale Order Request</a>
|
||||||
|
<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="sale_logistic_approval_template" model="mail.template">
|
||||||
|
<field name="name">Sale Logistic Approval</field>
|
||||||
|
<field name="email_from">${(object.user_id.email and '%s <%s>' % (object.user_id.company_id.name, object.user_id.email) or '')|safe}</field>
|
||||||
|
<field name="subject">Logistic Approval</field>
|
||||||
|
<field name="model_id" ref="sale.model_sale_order"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
|
||||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px; color: rgb(34, 34, 34); background-color: #FFF;">
|
||||||
|
<p>Dear Logistic,</p> <br/>
|
||||||
|
<p>Please Approve Sale Order bellow link </b> </p>
|
||||||
|
|
||||||
|
% set setup_url = object.make_url()
|
||||||
|
<br/><br/>
|
||||||
|
<a href="${setup_url}" style="background-color: #1abc9c;padding: 20px;text-decoration: none;color: #fff;border-radius: 5px;font-size: 16px;" class="o_default_snippet_text">Approve Sale Order Request</a>
|
||||||
|
<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="sale_credit_controller_template" model="mail.template">
|
||||||
|
<field name="name">Credit controller</field>
|
||||||
|
<field name="subject">Credit Controller Confirm Sale Order</field>
|
||||||
|
<field name="model_id" ref="sale.model_sale_order"/>
|
||||||
|
<field name="auto_delete" eval="True"/>
|
||||||
|
<field name="body_html"><![CDATA[
|
||||||
|
|
||||||
|
<div style="font-family: 'Lucica Grande', Ubuntu, Arial, Verdana, sans-serif; font-size: 14px; color: rgb(34, 34, 34); background-color: #FFF;">
|
||||||
|
<p>Dear Credit Controller,</p> <br/>
|
||||||
|
<p>Please Approve Sale Order bellow link </b> </p>
|
||||||
|
|
||||||
|
% set setup_url = object.make_url()
|
||||||
|
<br/><br/>
|
||||||
|
<a href="${setup_url}" style="background-color: #1abc9c;padding: 20px;text-decoration: none;color: #fff;border-radius: 5px;font-size: 16px;" class="o_default_snippet_text">Approve Sale Order Request</a>
|
||||||
|
<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
]]></field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
8
MKS_Tradex_Backend_2/models/__init__.py
Executable file
8
MKS_Tradex_Backend_2/models/__init__.py
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import purchase_requisition
|
||||||
|
from . import purchase_order
|
||||||
|
from . import stock_picking
|
||||||
|
from . import sale_order
|
||||||
|
from . import account_invoice
|
||||||
52
MKS_Tradex_Backend_2/models/account_invoice.py
Executable file
52
MKS_Tradex_Backend_2/models/account_invoice.py
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||||
|
|
||||||
|
class account_move(models.Model):
|
||||||
|
_inherit = "account.move"
|
||||||
|
|
||||||
|
state = fields.Selection(selection_add=[('approval','Financial Approval')])
|
||||||
|
|
||||||
|
def make_invoice_url(self):
|
||||||
|
for invoice in self:
|
||||||
|
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url', default='http://localhost:8069')
|
||||||
|
if base_url:
|
||||||
|
base_url += '/web/login?db=%s&login=%s&key=%s#id=%s&model=%s' % (
|
||||||
|
self._cr.dbname, '', '', invoice.id, 'account.move')
|
||||||
|
return base_url
|
||||||
|
|
||||||
|
def get_email(self):
|
||||||
|
group_id = self.env['ir.model.data'].get_object_reference('account', 'group_account_manager')[1]
|
||||||
|
email = ''
|
||||||
|
if group_id:
|
||||||
|
group_id = self.env['res.groups'].browse(group_id)
|
||||||
|
for user in group_id.users:
|
||||||
|
if user.partner_id.email:
|
||||||
|
if email:
|
||||||
|
email = email+','+user.partner_id.email
|
||||||
|
else:
|
||||||
|
email = user.partner_id.email
|
||||||
|
return email
|
||||||
|
|
||||||
|
def send_invoice_approval_mail(self):
|
||||||
|
email = self.get_email()
|
||||||
|
if email:
|
||||||
|
mtp =self.env['mail.template']
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
template_id = ir_model_data.get_object_reference('MKS_Tradex_Backend_2', 'invoice_approval_mail_template')
|
||||||
|
mail_tem=mtp.browse(template_id[1])
|
||||||
|
mail_tem.write({'email_to': email})
|
||||||
|
mail_tem.send_mail(self.id,True)
|
||||||
|
|
||||||
|
|
||||||
|
def action_post(self):
|
||||||
|
if self.env.user.has_group('account.group_account_manager'):
|
||||||
|
return super(account_move,self).action_post()
|
||||||
|
else:
|
||||||
|
if self.type in ['out_invoice','out_refund','in_invoice','in_refund'] and self.state == 'draft':
|
||||||
|
self.send_invoice_approval_mail()
|
||||||
|
self.state = 'approval'
|
||||||
|
else:
|
||||||
|
return super(account_move,self).action_post()
|
||||||
|
|
||||||
75
MKS_Tradex_Backend_2/models/purchase_order.py
Executable file
75
MKS_Tradex_Backend_2/models/purchase_order.py
Executable file
@@ -0,0 +1,75 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||||
|
|
||||||
|
class purchase_order(models.Model):
|
||||||
|
_inherit = "purchase.order"
|
||||||
|
|
||||||
|
state = fields.Selection([
|
||||||
|
('draft', 'RFQ'),
|
||||||
|
('sent', 'RFQ Sent'),
|
||||||
|
('approved', 'RFQ Approved'),
|
||||||
|
('po_approval', 'PO Approval'),
|
||||||
|
('to approve', 'To Approve'),
|
||||||
|
('purchase', 'Purchase Order'),
|
||||||
|
('done', 'Locked'),
|
||||||
|
('cancel', 'Cancelled')
|
||||||
|
], string='Status', readonly=True, index=True, copy=False, default='draft', tracking=True)
|
||||||
|
|
||||||
|
def make_url(self):
|
||||||
|
record_id = self.id
|
||||||
|
menu_id = self.env.ref('purchase.menu_purchase_rfq').id
|
||||||
|
action_id = self.env.ref('purchase.purchase_rfq').id
|
||||||
|
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
|
||||||
|
if base_url:
|
||||||
|
base_url += \
|
||||||
|
'/web?#id=%s&view_type=form&model=%s&menu_id=%s&action=%s' % (
|
||||||
|
self.id, self._name, menu_id, action_id)
|
||||||
|
return base_url
|
||||||
|
|
||||||
|
def action_manager_approval(self):
|
||||||
|
group_id = self.env['ir.model.data'].get_object_reference('MKS_Tradex_Backend_2', 'group_purchase_coordinator')[1]
|
||||||
|
if group_id:
|
||||||
|
browse_group = self.env['res.groups'].browse(group_id)
|
||||||
|
for user in browse_group.users:
|
||||||
|
manager_mail = user.partner_id.email
|
||||||
|
mtp =self.env['mail.template']
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
template_id = ir_model_data.get_object_reference('MKS_Tradex_Backend_2', 'purchase_req_coordinator_template')
|
||||||
|
mail_tem=mtp.browse(template_id[1])
|
||||||
|
mail_tem.send_mail(self.id,True)
|
||||||
|
mail_tem.write({'email_to': manager_mail})
|
||||||
|
self.state = 'approved'
|
||||||
|
|
||||||
|
def button_confirm_mks(self):
|
||||||
|
group_id = self.env['ir.model.data'].get_object_reference('purchase', 'group_purchase_manager')[1]
|
||||||
|
if group_id:
|
||||||
|
browse_group = self.env['res.groups'].browse(group_id)
|
||||||
|
for user in browse_group.users:
|
||||||
|
manager_mail = user.partner_id.email
|
||||||
|
mtp =self.env['mail.template']
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
template_id = ir_model_data.get_object_reference('MKS_Tradex_Backend_2', 'purchase_req_manager_template')
|
||||||
|
mail_tem=mtp.browse(template_id[1])
|
||||||
|
mail_tem.send_mail(self.id,True)
|
||||||
|
mail_tem.write({'email_to': manager_mail})
|
||||||
|
self.state = 'po_approval'
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def button_confirm(self):
|
||||||
|
for order in self:
|
||||||
|
if order.state not in ['draft', 'sent','approved','po_approval']:
|
||||||
|
continue
|
||||||
|
order._add_supplier_to_product()
|
||||||
|
# Deal with double validation process
|
||||||
|
if order.company_id.po_double_validation == 'one_step'\
|
||||||
|
or (order.company_id.po_double_validation == 'two_step'\
|
||||||
|
and order.amount_total < self.env.company.currency_id._convert(
|
||||||
|
order.company_id.po_double_validation_amount, order.currency_id, order.company_id, order.date_order or fields.Date.today()))\
|
||||||
|
or order.user_has_groups('purchase.group_purchase_manager'):
|
||||||
|
order.button_approve()
|
||||||
|
else:
|
||||||
|
order.write({'state': 'to approve'})
|
||||||
|
return True
|
||||||
123
MKS_Tradex_Backend_2/models/purchase_requisition.py
Executable file
123
MKS_Tradex_Backend_2/models/purchase_requisition.py
Executable file
@@ -0,0 +1,123 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||||
|
|
||||||
|
|
||||||
|
PURCHASE_REQUISITION_STATES = [
|
||||||
|
('draft', 'Draft'),
|
||||||
|
('approval', 'Approval'),
|
||||||
|
('manager_approval','Manager Approval'),
|
||||||
|
('approved','Approved'),
|
||||||
|
('ongoing', 'Ongoing'),
|
||||||
|
('in_progress', 'Confirmed'),
|
||||||
|
('open', 'Bid Selection'),
|
||||||
|
('done', 'Closed'),
|
||||||
|
('cancel', 'Cancelled'),
|
||||||
|
]
|
||||||
|
|
||||||
|
class purchase_requisition(models.Model):
|
||||||
|
_inherit = "purchase.requisition"
|
||||||
|
|
||||||
|
state = fields.Selection(PURCHASE_REQUISITION_STATES,
|
||||||
|
'Status', tracking=True, required=True,
|
||||||
|
copy=False, default='draft')
|
||||||
|
|
||||||
|
state_blanket_order = fields.Selection(PURCHASE_REQUISITION_STATES, compute='_set_state')
|
||||||
|
|
||||||
|
@api.depends('state')
|
||||||
|
def _set_state(self):
|
||||||
|
self.state_blanket_order = self.state
|
||||||
|
|
||||||
|
def basick_information(self):
|
||||||
|
order_table=''
|
||||||
|
order_table +='''
|
||||||
|
<table border=1 width=100% style='margin-top: 10px;'>
|
||||||
|
<tr>
|
||||||
|
<td width="20%"><center><b>Purchase Representative</b></center></td>
|
||||||
|
<td width="20%"><center><b>Agreement Type</b></center></td>
|
||||||
|
<td width="20%"><center><b>Vendor</b></center></td>
|
||||||
|
<td width="20%"><center><b>Agreement Deadline</b></center></td>
|
||||||
|
<td width="20%"><center><b>Delivery Date</b></center></td>
|
||||||
|
</tr>
|
||||||
|
'''
|
||||||
|
Purchase_rep = self.user_id and self.user_id.name or ' '
|
||||||
|
agreement_type = self.type_id and self.type_id.name or ' '
|
||||||
|
vendor = self.vendor_id and self.vendor_id.name or ' '
|
||||||
|
agreement_deadline = self.date_end or ' '
|
||||||
|
delivery_date = self.schedule_date or ' '
|
||||||
|
order_table += "<tr>" + '<td align="center">' + Purchase_rep + '</td>' + '<td align="center">' + str(agreement_type) + '</td>' + '<td align="center">' + vendor + '</td>' + '<td align="center">' + str(agreement_deadline) + '</td>' + '<td align="center">' + str(delivery_date) + '</td>' + "</tr>"
|
||||||
|
|
||||||
|
order_table += '''
|
||||||
|
</table>
|
||||||
|
'''
|
||||||
|
|
||||||
|
return order_table
|
||||||
|
|
||||||
|
|
||||||
|
def line_information(self):
|
||||||
|
order_table=''
|
||||||
|
order_table +='''
|
||||||
|
<table border=1 width=100% style='margin-top: 10px;'>
|
||||||
|
<tr>
|
||||||
|
<td width="40%"><left><b>Product</b></center></td>
|
||||||
|
<td width="15%"><center><b>Quantity</b></center></td>
|
||||||
|
<td width="15%"><center><b>Order Quantity </b></center></td>
|
||||||
|
<td width="15%"><center><b>Scheduled Date</b></center></td>
|
||||||
|
<td width="15%"><center><b>Unit Price</b></center></td>
|
||||||
|
</tr>
|
||||||
|
'''
|
||||||
|
for line in self.line_ids:
|
||||||
|
product_name = line.product_id and line.product_id.name or ' '
|
||||||
|
schedule_date = line.schedule_date or ' '
|
||||||
|
order_table += "<tr>" + '<td align="left">' + product_name + '</td>' + '<td align="center">' + str(line.product_qty) + '</td>' + '<td align="center">' + str(line.qty_ordered) + '</td>' + '<td align="center">' + str(schedule_date) + '</td>' + '<td align="center">' + str(line.price_unit) + '</td>' + "</tr>"
|
||||||
|
order_table += '''
|
||||||
|
</table>
|
||||||
|
'''
|
||||||
|
|
||||||
|
return order_table
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def make_url(self):
|
||||||
|
record_id = self.id
|
||||||
|
menu_id = self.env.ref('purchase_requisition.menu_purchase_requisition_pro_mgt').id
|
||||||
|
action_id = self.env.ref('purchase_requisition.action_purchase_requisition').id
|
||||||
|
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
|
||||||
|
if base_url:
|
||||||
|
base_url += \
|
||||||
|
'/web?#id=%s&view_type=form&model=%s&menu_id=%s&action=%s' % (
|
||||||
|
self.id, self._name, menu_id, action_id)
|
||||||
|
return base_url
|
||||||
|
|
||||||
|
def action_approval(self):
|
||||||
|
group_id = self.env['ir.model.data'].get_object_reference('MKS_Tradex_Backend_2', 'group_purchase_coordinator')[1]
|
||||||
|
if group_id:
|
||||||
|
browse_group = self.env['res.groups'].browse(group_id)
|
||||||
|
for user in browse_group.users:
|
||||||
|
coordinator_mail = user.partner_id.email
|
||||||
|
mtp =self.env['mail.template']
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
template_id = ir_model_data.get_object_reference('MKS_Tradex_Backend_2', 'purchase_coordinator_template')
|
||||||
|
mail_tem=mtp.browse(template_id[1])
|
||||||
|
mail_tem.send_mail(self.id,True)
|
||||||
|
mail_tem.write({'email_to': coordinator_mail})
|
||||||
|
self.state = 'approval'
|
||||||
|
|
||||||
|
def action_coordinator_approval(self):
|
||||||
|
group_id = self.env['ir.model.data'].get_object_reference('purchase', 'group_purchase_manager')[1]
|
||||||
|
if group_id:
|
||||||
|
browse_group = self.env['res.groups'].browse(group_id)
|
||||||
|
for user in browse_group.users:
|
||||||
|
manager_mail = user.partner_id.email
|
||||||
|
mtp =self.env['mail.template']
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
template_id = ir_model_data.get_object_reference('MKS_Tradex_Backend_2', 'purchase_manager_template')
|
||||||
|
mail_tem=mtp.browse(template_id[1])
|
||||||
|
mail_tem.send_mail(self.id,True)
|
||||||
|
mail_tem.write({'email_to': manager_mail})
|
||||||
|
self.state = 'manager_approval'
|
||||||
|
|
||||||
|
def action_manager_approval(self):
|
||||||
|
self.state = 'approved'
|
||||||
|
|
||||||
103
MKS_Tradex_Backend_2/models/sale_order.py
Executable file
103
MKS_Tradex_Backend_2/models/sale_order.py
Executable file
@@ -0,0 +1,103 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||||
|
|
||||||
|
class sale_order(models.Model):
|
||||||
|
_inherit = "sale.order"
|
||||||
|
|
||||||
|
# logistics_id = fields.Many2one('res.users',string="Logistics Users")
|
||||||
|
# credit_controller_id = fields.Many2one('res.users',string="Credit Controller")
|
||||||
|
|
||||||
|
state = fields.Selection([
|
||||||
|
('draft', 'Quotation'),
|
||||||
|
('approval', 'RFQ approval'),
|
||||||
|
('approved', 'RFQ Approved'),
|
||||||
|
('logistics_approval', 'Logistics Approval'),
|
||||||
|
('logistics_approved', 'Logistics Approved'),
|
||||||
|
('credit_approval', 'Credit Approval'),
|
||||||
|
('sent', 'Quotation Sent'),
|
||||||
|
('sale', 'Sales Order'),
|
||||||
|
('done', 'Locked'),
|
||||||
|
('cancel', 'Cancelled'),
|
||||||
|
], string='Status', readonly=True, copy=False, index=True, tracking=3, default='draft')
|
||||||
|
|
||||||
|
def make_url(self):
|
||||||
|
record_id = self.id
|
||||||
|
menu_id = self.env.ref('sale.menu_sale_quotations').id
|
||||||
|
action_id = self.env.ref('sale.action_quotations_with_onboarding').id
|
||||||
|
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
|
||||||
|
if base_url:
|
||||||
|
base_url += \
|
||||||
|
'/web?#id=%s&view_type=form&model=%s&menu_id=%s&action=%s' % (
|
||||||
|
self.id, self._name, menu_id, action_id)
|
||||||
|
return base_url
|
||||||
|
|
||||||
|
|
||||||
|
def action_confirm_approval_request(self):
|
||||||
|
group_id = self.env['ir.model.data'].get_object_reference('sales_team', 'group_sale_manager')[1]
|
||||||
|
if group_id:
|
||||||
|
browse_group = self.env['res.groups'].browse(group_id)
|
||||||
|
for user in browse_group.users:
|
||||||
|
print ("=====",user.name)
|
||||||
|
manager_mail = user.partner_id.email
|
||||||
|
mtp =self.env['mail.template']
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
template_id = ir_model_data.get_object_reference('MKS_Tradex_Backend_2', 'sale_manager_template')
|
||||||
|
mail_tem=mtp.browse(template_id[1])
|
||||||
|
mail_tem.write({'email_to': manager_mail})
|
||||||
|
mail_tem.send_mail(self.id,True)
|
||||||
|
self.state = 'approval'
|
||||||
|
return True
|
||||||
|
|
||||||
|
def action_manager_approval(self):
|
||||||
|
user_email = self.user_id.partner_id.email
|
||||||
|
manager = self.env.user.partner_id.email
|
||||||
|
mtp =self.env['mail.template']
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
template_id = ir_model_data.get_object_reference('MKS_Tradex_Backend_2', 'sale_user_template')
|
||||||
|
mail_tem=mtp.browse(template_id[1])
|
||||||
|
mail_tem.send_mail(self.id,True)
|
||||||
|
mail_tem.write({'email_from': manager,'email_to': user_email})
|
||||||
|
self.state = 'approved'
|
||||||
|
return True
|
||||||
|
|
||||||
|
def action_logistics_approval(self):
|
||||||
|
group_id = self.env['ir.model.data'].get_object_reference('MKS_Tradex_Backend_2', 'group_sale_logistics')[1]
|
||||||
|
if group_id:
|
||||||
|
browse_group = self.env['res.groups'].browse(group_id)
|
||||||
|
for user in browse_group.users:
|
||||||
|
manager_mail = user.partner_id.email
|
||||||
|
mtp =self.env['mail.template']
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
template_id = ir_model_data.get_object_reference('MKS_Tradex_Backend_2', 'sale_logistic_approval_template')
|
||||||
|
mail_tem=mtp.browse(template_id[1])
|
||||||
|
mail_tem.send_mail(self.id,True)
|
||||||
|
mail_tem.write({'email_to': manager_mail})
|
||||||
|
self.state = 'logistics_approval'
|
||||||
|
return True
|
||||||
|
|
||||||
|
def action_logistics_approve(self):
|
||||||
|
group_id = self.env['ir.model.data'].get_object_reference('MKS_Tradex_Backend_2', 'group_credit_controller')[1]
|
||||||
|
if group_id:
|
||||||
|
browse_group = self.env['res.groups'].browse(group_id)
|
||||||
|
for user in browse_group.users:
|
||||||
|
credit_controller = user.partner_id.email
|
||||||
|
user_email = self.user_id.partner_id.email
|
||||||
|
mtp =self.env['mail.template']
|
||||||
|
ir_model_data = self.env['ir.model.data']
|
||||||
|
template_id = ir_model_data.get_object_reference('MKS_Tradex_Backend_2', 'sale_credit_controller_template')
|
||||||
|
mail_tem=mtp.browse(template_id[1])
|
||||||
|
mail_tem.send_mail(self.id,True)
|
||||||
|
mail_tem.write({'email_from': user_email,'email_to': credit_controller})
|
||||||
|
self.state = 'sale'
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def action_credit_approval(self):
|
||||||
|
self.state = 'credit_approval'
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
16
MKS_Tradex_Backend_2/models/stock_picking.py
Executable file
16
MKS_Tradex_Backend_2/models/stock_picking.py
Executable file
@@ -0,0 +1,16 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||||
|
|
||||||
|
class stock_picking(models.Model):
|
||||||
|
_inherit = "stock.picking"
|
||||||
|
|
||||||
|
state = fields.Selection(selection_add=[('qa_approval', 'QA approval')],
|
||||||
|
)
|
||||||
|
|
||||||
|
def button_validate_qa_approval(self):
|
||||||
|
self.state = 'qa_approval'
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
14
MKS_Tradex_Backend_2/security/account_security.xml
Executable file
14
MKS_Tradex_Backend_2/security/account_security.xml
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="0">
|
||||||
|
|
||||||
|
<record id="account.group_account_invoice" model="res.groups">
|
||||||
|
<field name="name">Accountant</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="account.group_account_manager" model="res.groups">
|
||||||
|
<field name="name">Finance Manager</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
45
MKS_Tradex_Backend_2/security/purchase_security.xml
Normal file
45
MKS_Tradex_Backend_2/security/purchase_security.xml
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<data noupdate="0">
|
||||||
|
|
||||||
|
<record id="purchase.group_purchase_user" model="res.groups">
|
||||||
|
<field name="name">Store Keeper</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="group_purchase_coordinator" model="res.groups">
|
||||||
|
<field name="name">Purchase Coordinator</field>
|
||||||
|
<field name="implied_ids" eval="[(4, ref('purchase.group_purchase_user'))]"/>
|
||||||
|
<field name="category_id" ref="base.module_category_operations_purchase"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="purchase.group_purchase_manager" model="res.groups">
|
||||||
|
<field name="name">Management</field>
|
||||||
|
<field name="implied_ids" eval="[(4, ref('group_purchase_coordinator'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!-- sale access right-->
|
||||||
|
|
||||||
|
<record id="sales_team.group_sale_salesman" model="res.groups">
|
||||||
|
<field name="name">Store Keeper</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="group_sale_logistics" model="res.groups">
|
||||||
|
<field name="name">Logistics and Warehouse Coordinator</field>
|
||||||
|
<field name="category_id" ref="base.module_category_sales_sales"/>
|
||||||
|
<field name="implied_ids" eval="[(4, ref('sales_team.group_sale_salesman_all_leads'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="group_credit_controller" model="res.groups">
|
||||||
|
<field name="name">Credit Controller</field>
|
||||||
|
<field name="category_id" ref="base.module_category_sales_sales"/>
|
||||||
|
<field name="implied_ids" eval="[(4, ref('group_sale_logistics'))]"/>
|
||||||
|
</record>
|
||||||
|
<record id="sales_team.group_sale_manager" model="res.groups">
|
||||||
|
<field name="name">Management</field>
|
||||||
|
<field name="category_id" ref="base.module_category_sales_sales"/>
|
||||||
|
<field name="implied_ids" eval="[(4, ref('group_credit_controller'))]"/>
|
||||||
|
<field name="users" eval="[(4, ref('base.user_root')), (4, ref('base.user_admin'))]"/>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</data>
|
||||||
|
</odoo>
|
||||||
17
MKS_Tradex_Backend_2/views/account_move_views.xml
Normal file
17
MKS_Tradex_Backend_2/views/account_move_views.xml
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_account_move_inherit_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.account.move.inherit.form</field>
|
||||||
|
<field name="model">account.move</field>
|
||||||
|
<field name="inherit_id" ref="account.view_move_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//button[@name='action_post']" position="after">
|
||||||
|
<button name="action_post" string="Post" class="oe_highlight" type="object" groups="account.group_account_manager" attrs="{'invisible': [('state', '!=', 'approval')]}"/>
|
||||||
|
|
||||||
|
<button name="button_cancel" string="Cancel Entry" type="object" groups="account.group_account_invoice" attrs="{'invisible' : ['|', ('id', '=', False), ('state', '!=', 'approval')]}"/>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
39
MKS_Tradex_Backend_2/views/purchase_order_views.xml
Normal file
39
MKS_Tradex_Backend_2/views/purchase_order_views.xml
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_purchase_order_inherit_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.purchase.order.inherit.form</field>
|
||||||
|
<field name="model">purchase.order</field>
|
||||||
|
<field name="inherit_id" ref="purchase.purchase_order_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//button[@name='print_quotation']" position="replace">
|
||||||
|
<button name="print_quotation" string="Print RFQ" type="object" states="approved" class="oe_highlight" groups="base.group_user"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='action_rfq_send']" position="replace">
|
||||||
|
<button name="action_rfq_send" states="approved" string="Send by Email" type="object" context="{'send_rfq':True}" class="oe_highlight"/>
|
||||||
|
|
||||||
|
<button name="action_manager_approval" states="draft" string="Manager Approval"
|
||||||
|
type="object" class="oe_highlight" groups="purchase.group_purchase_manager"/>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@id='bid_confirm']" position="replace">
|
||||||
|
<button name="button_confirm" type="object" states="sent" string="Confirm Order" class="oe_highlight" id="bid_confirm"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@id='draft_confirm']" position="replace">
|
||||||
|
<button name="button_confirm_mks" type="object" states="approved" groups="MKS_Tradex_Backend_2.group_purchase_coordinator" string="Confirm Order" id="draft_confirm_mks"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='print_quotation']" position="after">
|
||||||
|
<button name="button_confirm" groups="purchase.group_purchase_manager" type="object" states="po_approval" string="Confirm Order" class="oe_highlight" />
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//button[@name='button_cancel']" position="replace">
|
||||||
|
<button name="button_cancel" states="draft,to approve,sent,purchase,po_approval" string="Cancel" type="object"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
35
MKS_Tradex_Backend_2/views/purchase_requisition_views.xml
Normal file
35
MKS_Tradex_Backend_2/views/purchase_requisition_views.xml
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_purchase_requisition_inherit_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.purchase.requisition.inherit.form</field>
|
||||||
|
<field name="model">purchase.requisition</field>
|
||||||
|
<field name="inherit_id" ref="purchase_requisition.view_purchase_requisition_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//header" position="replace">
|
||||||
|
<header>
|
||||||
|
<button name="363" type="action" string="New Quotation" attrs="{'invisible': [('state', '!=', 'open')]}"/>
|
||||||
|
<button name="363" type="action" string="New Quotation" class="btn-primary" attrs="{'invisible': [('state', 'not in', ('in_progress', 'ongoing'))]}" groups="MKS_Tradex_Backend_2.group_purchase_coordinator,purchase.group_purchase_manager"/>
|
||||||
|
<!-- <button name="action_in_progress" states="draft" string="Confirm" type="object" class="btn-primary"/>-->
|
||||||
|
<button name="action_open" states="in_progress" string="Validate" groups="MKS_Tradex_Backend_2.group_purchase_coordinator,purchase.group_purchase_manager" type="object" class="btn-primary"/>
|
||||||
|
<button name="action_done" states="open,ongoing" string="Close" type="object" class="btn-primary"/>
|
||||||
|
<button name="action_draft" states="cancel" string="Reset to Draft" type="object"/>
|
||||||
|
<!-- <button name="action_cancel" states="draft,in_progress,ongoing" string="Cancel" type="object"/>-->
|
||||||
|
<button name="action_cancel" states="draft,approval,manager_approval,approved,in_progress,ongoing" string="Cancel" type="object"/>
|
||||||
|
<button name="action_in_progress" states="approved" string="Confirm" type="object" class="btn-primary"
|
||||||
|
groups="MKS_Tradex_Backend_2.group_purchase_coordinator"/>
|
||||||
|
|
||||||
|
<button name="action_approval" states="draft" string="Confirm" type="object" class="btn-primary" groups="purchase.group_purchase_user"/>
|
||||||
|
|
||||||
|
<button name="action_coordinator_approval" states="approval" string="Coordinator Approval" type="object" class="btn-primary" groups="MKS_Tradex_Backend_2.group_purchase_coordinator"/>
|
||||||
|
|
||||||
|
<button name="action_manager_approval" states="manager_approval" string="Manager Approval" type="object" class="btn-primary" groups="purchase.group_purchase_manager"/>
|
||||||
|
<field name="state" widget="statusbar" statusbar_visible="draft,in_progress,open,done" attrs="{'invisible': [('is_quantity_copy', '=', 'none')]}"/>
|
||||||
|
<field name="state_blanket_order" widget="statusbar" statusbar_visible="draft,ongoing,done" attrs="{'invisible': [('is_quantity_copy', '!=', 'none')]}"/>
|
||||||
|
</header>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
47
MKS_Tradex_Backend_2/views/sale_order_view.xml
Normal file
47
MKS_Tradex_Backend_2/views/sale_order_view.xml
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="mks_sale_order_inherit_form" model="ir.ui.view">
|
||||||
|
<field name="name">mks.sale.order.inherit.form</field>
|
||||||
|
<field name="model">sale.order</field>
|
||||||
|
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//button[@name='action_confirm'][2]" position="replace">
|
||||||
|
|
||||||
|
<button name="action_confirm" groups="MKS_Tradex_Backend_2.group_credit_controller" string="Sale Confirm" class="btn-primary" type="object" attrs="{'invisible': [('state', 'not in', ['sale'])]}"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='action_quotation_send']" position="after">
|
||||||
|
<button name="action_manager_approval" groups = "sales_team.group_sale_manager" string="Manager Approval" type="object" attrs="{'invisible': [('state', 'not in', ['approval'])]}"/>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='action_quotation_send']" position="replace">
|
||||||
|
<button name="action_quotation_send" string="Send by Email" type="object" states="approved" class="btn-primary"/>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
<xpath expr="//button[@name='action_confirm']" position="after">
|
||||||
|
<button name="action_confirm_approval_request" groups="sales_team.group_sale_salesman" string="Confirm" class="btn-primary" type="object" attrs="{'invisible': [('state', 'not in', ['draft'])]}"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<!-- <xpath expr="//button[@name='action_confirm']" position="after">-->
|
||||||
|
<!-- <button name="action_cancel" states="draft,sent,sale,approved,logistics_approved,logistics_approval" type="object" string="Cancel"/>-->
|
||||||
|
<!-- </xpath>-->
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='action_confirm']" position="after">
|
||||||
|
<button name="action_logistics_approval" groups="sales_team.group_sale_salesman" states="approved" type="object" string="Logistics Approval"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='action_confirm']" position="after">
|
||||||
|
<button name="action_logistics_approve" groups="MKS_Tradex_Backend_2.group_sale_logistics" states="logistics_approval" type="object" string="Confirm"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
36
MKS_Tradex_Backend_2/views/stock_picking.xml
Normal file
36
MKS_Tradex_Backend_2/views/stock_picking.xml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
<record id="view_stock_picking_inherit_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.stock.picking.inherit.form</field>
|
||||||
|
<field name="model">stock.picking</field>
|
||||||
|
<field name="inherit_id" ref="stock.view_picking_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//button[@name='button_validate']" position="replace">
|
||||||
|
<button name="button_validate" attrs="{'invisible': [('state', '!=', ('qa_approval'))]}" string="Validate" type="object" class="oe_highlight" groups="stock.group_stock_user"/>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='button_scrap']" position="after">
|
||||||
|
<button name="button_validate_qa_approval" states="assigned" string="QA Validate" type="object" class="oe_highlight" groups="stock.group_stock_user"/>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//field[@name='state']" position="replace">
|
||||||
|
<field name="state" widget="statusbar" statusbar_visible="draft,confirmed,partially_available,assigned,qa_approval,done"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='do_print_picking']" position="replace">
|
||||||
|
<button name="do_print_picking" string="Print" groups="stock.group_stock_user" type="object" attrs="{'invisible': ['|', ('state', 'not in', ('qa_approval', 'partially_available')), ('is_locked', '=', False)]}"/>
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
<xpath expr="//button[@name='action_cancel']" position="replace">
|
||||||
|
<button name="action_cancel" attrs="{'invisible': ['|', ('state', 'not in', ('qa_approval', 'confirmed', 'partially_available', 'draft', 'waiting')), ('is_locked', '=', False)]}" string="Cancel" groups="base.group_user" type="object"/>
|
||||||
|
|
||||||
|
</xpath>
|
||||||
|
|
||||||
|
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
4
tradex_backend_2/__init__.py
Executable file
4
tradex_backend_2/__init__.py
Executable file
@@ -0,0 +1,4 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import models
|
||||||
|
from . import wizard
|
||||||
20
tradex_backend_2/__manifest__.py
Executable file
20
tradex_backend_2/__manifest__.py
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
{
|
||||||
|
'name': 'Tradex Backend',
|
||||||
|
'version': '13.0.1.0',
|
||||||
|
'category': 'Stock',
|
||||||
|
'description': """
|
||||||
|
This module allows you to add location in stock move
|
||||||
|
d
|
||||||
|
""",
|
||||||
|
'depends': ['sale_management','sale_stock'],
|
||||||
|
'data': [
|
||||||
|
'security/ir.model.access.csv',
|
||||||
|
'wizard/stock_location_qty_views.xml',
|
||||||
|
'wizard/inventory_view_report.xml',
|
||||||
|
'views/stock_move_views.xml',
|
||||||
|
'views/sale_order_views.xml',
|
||||||
|
'views/inventory_view.xml',
|
||||||
|
],
|
||||||
|
|
||||||
|
}
|
||||||
3
tradex_backend_2/models/__init__.py
Executable file
3
tradex_backend_2/models/__init__.py
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import stock_move_location_lines
|
||||||
59
tradex_backend_2/models/stock_move_location_lines.py
Executable file
59
tradex_backend_2/models/stock_move_location_lines.py
Executable file
@@ -0,0 +1,59 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models, SUPERUSER_ID, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
class stock_move(models.Model):
|
||||||
|
_inherit = 'stock.move'
|
||||||
|
|
||||||
|
move_location_lines = fields.One2many('stock.move.location.lines','move_id', string='Move Location Lines')
|
||||||
|
|
||||||
|
|
||||||
|
# @api.constrains('move_location_lines','move_location_lines.qty')
|
||||||
|
# def check_location_quantity(self):
|
||||||
|
# for move in self:
|
||||||
|
# if move.move_location_lines:
|
||||||
|
# qty = 0
|
||||||
|
# for line in move.move_location_lines:
|
||||||
|
# qty += line.qty
|
||||||
|
#
|
||||||
|
# if qty > move.product_uom_qty:
|
||||||
|
# raise ValidationError(_("Location Quantity must less or equal %s Quantity")% move.product_uom_qty)
|
||||||
|
|
||||||
|
@api.constrains('move_location_lines','move_location_lines.qty')
|
||||||
|
def check_location_quantity(self):
|
||||||
|
for move in self:
|
||||||
|
if move.move_line_nosuggest_ids:
|
||||||
|
base_qty = 0
|
||||||
|
location_qty = 0
|
||||||
|
for base_move in move.move_line_nosuggest_ids:
|
||||||
|
base_qty += base_move.qty_done
|
||||||
|
for location_move in move.move_location_lines:
|
||||||
|
location_qty += location_move.qty
|
||||||
|
if location_qty > base_qty:
|
||||||
|
raise ValidationError(_("Location Quantity must less or equal %s Quantity") % base_qty)
|
||||||
|
else:
|
||||||
|
raise ValidationError(_("Please add some done quantity in above table"))
|
||||||
|
|
||||||
|
class stock_move_location_lines(models.Model):
|
||||||
|
_name = "stock.move.location.lines"
|
||||||
|
|
||||||
|
def get_company_id(self):
|
||||||
|
company_id = False
|
||||||
|
if self.move_id and self.move_id.picking_id:
|
||||||
|
if self.move_id.picking_id and self.move_id.picking_id.location_dest_id:
|
||||||
|
if self.move_id.picking_id.location_dest_id.company_id:
|
||||||
|
company_id = self.move_id.picking_id.location_dest_id.company_id.id
|
||||||
|
return company_id
|
||||||
|
|
||||||
|
product_id = fields.Many2one('product.product', string='Product', required="1")
|
||||||
|
qty = fields.Float(string='Quantity', required="1")
|
||||||
|
uom = fields.Many2one('uom.uom', string='UOM', required="1")
|
||||||
|
location_id = fields.Many2one('stock.location', string='Location', required="1")
|
||||||
|
company_id = fields.Many2one('res.company', string='Owner', default=get_company_id)
|
||||||
|
move_id = fields.Many2one('stock.move', string='Move')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
2
tradex_backend_2/security/ir.model.access.csv
Normal file
2
tradex_backend_2/security/ir.model.access.csv
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||||
|
access_stock_move_location_lines_all,stock.move.lines.all,model_stock_move_location_lines,,1,1,1,1
|
||||||
|
74
tradex_backend_2/views/inventory_view.xml
Normal file
74
tradex_backend_2/views/inventory_view.xml
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (<http://www.devintellecs.com>).
|
||||||
|
|
||||||
|
For Module Support : devintelle@gmail.com or Skype : devintelle
|
||||||
|
-->
|
||||||
|
<odoo>
|
||||||
|
<!--form-->
|
||||||
|
<record id="form_backend_inventory_view" model="ir.ui.view">
|
||||||
|
<field name="name">form.backend.inventory.view</field>
|
||||||
|
<field name="model">stock.move.location.lines</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Inventory View Form View">
|
||||||
|
<sheet>
|
||||||
|
<group>
|
||||||
|
<group>
|
||||||
|
<field name="product_id" options="{'no_create': True}"/>
|
||||||
|
<field name="location_id" options="{'no_create': True}"/>
|
||||||
|
</group>
|
||||||
|
<group>
|
||||||
|
<field name="qty"/>
|
||||||
|
<field name="uom"/>
|
||||||
|
</group>
|
||||||
|
</group>
|
||||||
|
</sheet>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--Tree-->
|
||||||
|
<record id="tree_backend_inventory_view" model="ir.ui.view">
|
||||||
|
<field name="name">tree.backend.inventory.view</field>
|
||||||
|
<field name="model">stock.move.location.lines</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<tree string="Inventory View Tree View">
|
||||||
|
<field name="product_id"/>
|
||||||
|
<field name="qty"/>
|
||||||
|
<field name="uom"/>
|
||||||
|
<field name="location_id"/>
|
||||||
|
<field name="company_id"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--search view-->
|
||||||
|
<record id="search_backend_inventory_view" model="ir.ui.view">
|
||||||
|
<field name="name">Inventory View - Search</field>
|
||||||
|
<field name="model">stock.move.location.lines</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<search string="Inventory View Search">
|
||||||
|
<field name="product_id"/>
|
||||||
|
<group expand="0" string="Group By">
|
||||||
|
<filter name="location_id" string="Location" context="{'group_by':'location_id'}"/>
|
||||||
|
<filter name="company_id" string="Owner" context="{'group_by':'company_id'}"/>
|
||||||
|
</group>
|
||||||
|
</search>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--Action-->
|
||||||
|
<record id="action_backend_inventory_view" model="ir.actions.act_window">
|
||||||
|
<field name="name">Inventory View</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">stock.move.location.lines</field>
|
||||||
|
<field name="view_mode">tree,form</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<!--Menus-->
|
||||||
|
<menuitem name="Inventory View"
|
||||||
|
id="menu_backend_inventory_view"
|
||||||
|
parent="stock.menu_warehouse_report"
|
||||||
|
action="action_backend_inventory_view"
|
||||||
|
sequence="0"/>
|
||||||
|
</odoo>
|
||||||
20
tradex_backend_2/views/sale_order_views.xml
Executable file
20
tradex_backend_2/views/sale_order_views.xml
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (<http://www.devintellecs.com>).
|
||||||
|
|
||||||
|
For Module Support : devintelle@gmail.com or Skype : devintelle
|
||||||
|
-->
|
||||||
|
<odoo>
|
||||||
|
<record id="view_odoo_sale_order_inherit_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.odoo.sale.order.inherit.form</field>
|
||||||
|
<field name="model">sale.order</field>
|
||||||
|
<field name="inherit_id" ref="sale.view_order_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//field[@name='order_line']//tree//field[@name='company_id']" position="after">
|
||||||
|
<button name="%(tradex_backend_2.action_stock_location_quantity)d" string="location" type="action" icon="fa-list" width="0.1" context="{'default_product_id':product_id}"/>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
49
tradex_backend_2/views/stock_move_views.xml
Executable file
49
tradex_backend_2/views/stock_move_views.xml
Executable file
@@ -0,0 +1,49 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (<http://www.devintellecs.com>).
|
||||||
|
|
||||||
|
For Module Support : devintelle@gmail.com or Skype : devintelle
|
||||||
|
-->
|
||||||
|
<odoo>
|
||||||
|
<record id="view_stock_move_views_inherit_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.stock.move.views.inherit.form</field>
|
||||||
|
<field name="model">stock.move</field>
|
||||||
|
<field name="inherit_id" ref="stock.view_stock_move_operations"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//field[@name='move_line_ids']" position="after">
|
||||||
|
<field name="move_location_lines" context="{'default_product_id':product_id,'default_uom':product_uom}">
|
||||||
|
<tree editable="bottom">
|
||||||
|
<field name="product_id" readonly="1" force_save="1"/>
|
||||||
|
<field name="qty"/>
|
||||||
|
<field name="uom" readonly="1" force_save="1"/>
|
||||||
|
<field name="location_id"/>
|
||||||
|
<field name="company_id" invisible="1"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="view_stock_move_location_views_inherit_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.stock.move.location.views.inherit.form</field>
|
||||||
|
<field name="model">stock.move</field>
|
||||||
|
<field name="inherit_id" ref="stock.view_move_form"/>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<xpath expr="//group[1]" position="after">
|
||||||
|
<group string='Location Products'>
|
||||||
|
<field name="move_location_lines" context="{'default_product_id':product_id,'default_uom':product_uom}" nolabel="1">
|
||||||
|
<tree editable="bottom">
|
||||||
|
<field name="product_id"/>
|
||||||
|
<field name="qty"/>
|
||||||
|
<field name="uom"/>
|
||||||
|
<field name="location_id"/>
|
||||||
|
<field name="company_id" invisible="1"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</group>
|
||||||
|
</xpath>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
|
||||||
|
</odoo>
|
||||||
7
tradex_backend_2/wizard/__init__.py
Normal file
7
tradex_backend_2/wizard/__init__.py
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from . import stock_location_qty
|
||||||
|
from . import inventory_view_report
|
||||||
|
|
||||||
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
162
tradex_backend_2/wizard/inventory_view_report.py
Normal file
162
tradex_backend_2/wizard/inventory_view_report.py
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
import itertools
|
||||||
|
from operator import itemgetter
|
||||||
|
import operator
|
||||||
|
# ========For Excel=======
|
||||||
|
from io import BytesIO
|
||||||
|
import xlwt
|
||||||
|
from xlwt import easyxf, Formula
|
||||||
|
import base64
|
||||||
|
from datetime import datetime
|
||||||
|
# =======================
|
||||||
|
|
||||||
|
class inventory_view_report(models.TransientModel):
|
||||||
|
_name = "inventory.view.report"
|
||||||
|
_description = 'Inventory View Report'
|
||||||
|
|
||||||
|
product_ids = fields.Many2many('product.product', string='Products')
|
||||||
|
excel_file = fields.Binary('Excel File')
|
||||||
|
|
||||||
|
def create_excel_header(self,worksheet):
|
||||||
|
header_style = easyxf('font:height 300;pattern: pattern solid, fore_color silver_ega; align: horiz center, vert center;font:bold True;')
|
||||||
|
sub_header = easyxf('font:height 210;pattern: pattern solid, fore_color silver_ega;font:bold True;')
|
||||||
|
content = easyxf('font:height 200;')
|
||||||
|
worksheet.write_merge(2, 3, 2, 4, 'Inventory View Report ', header_style)
|
||||||
|
row=5
|
||||||
|
|
||||||
|
return worksheet, row+1
|
||||||
|
|
||||||
|
def create_excel_table_header(self,row,worksheet,company_ids):
|
||||||
|
header_style = easyxf('font:height 150;pattern: pattern solid, fore_color silver_ega; align: horiz center, vert center;font:bold True;' "borders: top thin,bottom thin,right thin, left thin")
|
||||||
|
worksheet.write(row, 0,'ITEM CODE', header_style)
|
||||||
|
worksheet.write(row, 1,'DESCRIPTION', header_style)
|
||||||
|
worksheet.write(row, 2,'TOTAL QUANTITY', header_style)
|
||||||
|
worksheet.write(row, 3,'LOCATION', header_style)
|
||||||
|
|
||||||
|
col=4
|
||||||
|
for company in company_ids:
|
||||||
|
worksheet.write(row, col,company.name, header_style)
|
||||||
|
col+=1
|
||||||
|
|
||||||
|
row+=1
|
||||||
|
|
||||||
|
return worksheet, row
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def get_company(self):
|
||||||
|
sql_query = """select DISTINCT sl.company_id from stock_move_location_lines as smll LEFT JOIN stock_location as sl ON sl.id = smll.location_id LEFT JOIN res_company as rc ON rc.id=sl.company_id where smll.product_id in %s"""
|
||||||
|
params = (tuple(self.product_ids.ids),)
|
||||||
|
self.env.cr.execute(sql_query, params)
|
||||||
|
results = self.env.cr.dictfetchall()
|
||||||
|
company_ids = [result.get('company_id') for result in results]
|
||||||
|
company_ids = self.env['res.company'].browse(company_ids)
|
||||||
|
return company_ids
|
||||||
|
|
||||||
|
def get_location(self,product_id):
|
||||||
|
sql_query = """select DISTINCT location_id from stock_move_location_lines where product_id = %s"""
|
||||||
|
params = (product_id.id,)
|
||||||
|
self.env.cr.execute(sql_query, params)
|
||||||
|
results = self.env.cr.dictfetchall()
|
||||||
|
location_ids = [result.get('location_id') for result in results]
|
||||||
|
location_ids = self.env['stock.location'].browse(location_ids)
|
||||||
|
return location_ids
|
||||||
|
|
||||||
|
|
||||||
|
def get_quantity(self,product,location,company):
|
||||||
|
sql_query = """select sum(smll.qty) from stock_move_location_lines as smll LEFT JOIN stock_location as sl ON sl.id = smll.location_id LEFT JOIN res_company as rc ON rc.id=sl.company_id where smll.product_id = %s and smll.location_id = %s and sl.company_id = %s"""
|
||||||
|
params = (product.id,location.id,company.id)
|
||||||
|
self.env.cr.execute(sql_query, params)
|
||||||
|
results = self.env.cr.dictfetchall()[0]
|
||||||
|
if results.get('sum'):
|
||||||
|
return results.get('sum')
|
||||||
|
return 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def create_excel_table_values(self,row,worksheet,company_ids):
|
||||||
|
header_style = easyxf('font:height 150;pattern: pattern solid, fore_color silver_ega; align: horiz center, vert center;font:bold True;' "borders: top thin,bottom thin,right thin, left thin")
|
||||||
|
content = easyxf('font:height 200; align: vert center;' "borders: top thin,bottom thin,right thin, left thin",num_format_str='0.00')
|
||||||
|
content_bold = easyxf('font:height 200; align: vert center;font:bold True;' "borders: top thin,bottom thin,right thin, left thin",num_format_str='0.00')
|
||||||
|
for product in self.product_ids:
|
||||||
|
location_ids = self.get_location(product)
|
||||||
|
if location_ids:
|
||||||
|
worksheet.write(row, 0,product.default_code, content)
|
||||||
|
worksheet.write(row, 1,product.name, content)
|
||||||
|
worksheet.write(row, 2,product.qty_available, content)
|
||||||
|
com_sum_row = row
|
||||||
|
row+=1
|
||||||
|
com_sum=[]
|
||||||
|
for company in company_ids:
|
||||||
|
com_sum.append({
|
||||||
|
'company_id':company.id,
|
||||||
|
'qty':0.0
|
||||||
|
})
|
||||||
|
for location in location_ids:
|
||||||
|
worksheet.write(row, 3, location.display_name, content)
|
||||||
|
col=4
|
||||||
|
total_qty = 0.0
|
||||||
|
for company_id in company_ids:
|
||||||
|
qty = self.get_quantity(product,location,company_id)
|
||||||
|
total_qty += qty
|
||||||
|
if qty:
|
||||||
|
for com in com_sum:
|
||||||
|
if com.get('company_id') == company_id.id:
|
||||||
|
com.update({
|
||||||
|
'qty':com.get('qty') + qty
|
||||||
|
})
|
||||||
|
|
||||||
|
worksheet.write(row, col, qty, content)
|
||||||
|
col+=1
|
||||||
|
worksheet.write(row, 2, total_qty, content_bold)
|
||||||
|
row+=1
|
||||||
|
s_c = 3
|
||||||
|
for company in company_ids:
|
||||||
|
s_c += 1
|
||||||
|
for com in com_sum:
|
||||||
|
if company.id == com.get('company_id'):
|
||||||
|
worksheet.write(com_sum_row, s_c, com.get('qty'), content_bold)
|
||||||
|
row+=1
|
||||||
|
|
||||||
|
return worksheet, row
|
||||||
|
|
||||||
|
|
||||||
|
def print_report(self):
|
||||||
|
workbook = xlwt.Workbook()
|
||||||
|
filename = 'Inventory View.xls'
|
||||||
|
worksheet = workbook.add_sheet('Inventory Views')
|
||||||
|
worksheet,row = self.create_excel_header(worksheet)
|
||||||
|
for i in range(0,200):
|
||||||
|
worksheet.col(i).width = 150 * 30
|
||||||
|
if i == 1:
|
||||||
|
worksheet.col(i).width = 230 * 30
|
||||||
|
|
||||||
|
for i in range(5,50):
|
||||||
|
worksheet.row(i).height_mismatch = True
|
||||||
|
worksheet.col(i).width = 130 * 30
|
||||||
|
worksheet.row(i).height = 20 * 20
|
||||||
|
|
||||||
|
company_ids = self.get_company()
|
||||||
|
worksheet,row = self.create_excel_table_header(row,worksheet,company_ids)
|
||||||
|
worksheet,row = self.create_excel_table_values(row,worksheet,company_ids)
|
||||||
|
|
||||||
|
# company_ids = self.env['res.company'].browse(company)
|
||||||
|
# print ("======",lines,company_ids)
|
||||||
|
# def create_excel_table_val(self,worksheet,company):
|
||||||
|
fp = BytesIO()
|
||||||
|
workbook.save(fp)
|
||||||
|
fp.seek(0)
|
||||||
|
excel_file = base64.encodestring(fp.read())
|
||||||
|
fp.close()
|
||||||
|
self.write({'excel_file': excel_file})
|
||||||
|
|
||||||
|
active_id = self.ids[0]
|
||||||
|
return {'type': 'ir.actions.act_url', 'url': 'web/content/?model=inventory.view.report&download=true&field=excel_file&id=%s&filename=%s' % (active_id, filename), 'target': 'new', }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
||||||
36
tradex_backend_2/wizard/inventory_view_report.xml
Normal file
36
tradex_backend_2/wizard/inventory_view_report.xml
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!--
|
||||||
|
Copyright (C) 2015 DevIntelle Consulting Service Pvt.Ltd (<http://www.devintellecs.com>).
|
||||||
|
|
||||||
|
For Module Support : devintelle@gmail.com or Skype : devintelle
|
||||||
|
-->
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="view_inventory_view_report_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.inventory.view.report.form</field>
|
||||||
|
<field name="model">inventory.view.report</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Inventory View Report">
|
||||||
|
<label for="product_ids"/>
|
||||||
|
<field name="product_ids" nolabel="1"/>
|
||||||
|
<footer>
|
||||||
|
<button name="print_report" string="Print" type="object" class="btn-primary"/>
|
||||||
|
or
|
||||||
|
<button string="Cancel" class="btn-default" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_inventory_view_report" model="ir.actions.act_window">
|
||||||
|
<field name="name">Inventory View Report</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">inventory.view.report</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="view_inventory_view_report_form"/>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<menuitem name="Inventory View Report" id="menu_odoo_inventory_view_report" parent="stock.menu_warehouse_report" action="action_inventory_view_report" sequence="100"/>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
45
tradex_backend_2/wizard/stock_location_qty.py
Normal file
45
tradex_backend_2/wizard/stock_location_qty.py
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||||
|
|
||||||
|
from odoo import api, fields, models, _
|
||||||
|
from odoo.exceptions import ValidationError
|
||||||
|
|
||||||
|
class stock_location_quantity(models.TransientModel):
|
||||||
|
_name = "stock.location.quantity"
|
||||||
|
_description = 'location quantity'
|
||||||
|
|
||||||
|
product_id = fields.Many2one('product.product', string='Product')
|
||||||
|
qty = fields.Float('Quantity On Hand')
|
||||||
|
location_lines = fields.One2many('stock.location.quantity.line','slq_id', string='Location Quantity Lines')
|
||||||
|
|
||||||
|
@api.model
|
||||||
|
def default_get(self, fields):
|
||||||
|
res = super(stock_location_quantity,self).default_get(fields)
|
||||||
|
if res.get('product_id'):
|
||||||
|
product_id = self.env['product.product'].browse(res.get('product_id'))
|
||||||
|
res.update({
|
||||||
|
'qty':product_id.qty_available
|
||||||
|
})
|
||||||
|
line_ids = self.env['stock.move.location.lines'].search([('product_id','=',product_id.id)])
|
||||||
|
vals = []
|
||||||
|
for line in line_ids:
|
||||||
|
vals.append((0,0,{
|
||||||
|
'location_id':line.location_id and line.location_id.id or False,
|
||||||
|
'quantity':line.qty or 0.0,
|
||||||
|
'company_id':line.company_id and line.company_id.id or False,
|
||||||
|
}))
|
||||||
|
res.update({'location_lines':vals})
|
||||||
|
return res
|
||||||
|
|
||||||
|
|
||||||
|
class stock_location_quantity_line(models.TransientModel):
|
||||||
|
_name = "stock.location.quantity.line"
|
||||||
|
_description = 'location quantity'
|
||||||
|
|
||||||
|
location_id = fields.Many2one('stock.location', string='Location')
|
||||||
|
quantity = fields.Float('Quantity')
|
||||||
|
slq_id = fields.Many2one('stock.location.quantity', string='Stock Location')
|
||||||
|
company_id = fields.Many2one('res.company', string='Owner')
|
||||||
|
|
||||||
|
# vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4:
|
||||||
|
|
||||||
38
tradex_backend_2/wizard/stock_location_qty_views.xml
Normal file
38
tradex_backend_2/wizard/stock_location_qty_views.xml
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<odoo>
|
||||||
|
|
||||||
|
<record id="view_stock_location_quantity_form" model="ir.ui.view">
|
||||||
|
<field name="name">view.stock.location.quantity.form</field>
|
||||||
|
<field name="model">stock.location.quantity</field>
|
||||||
|
<field name="arch" type="xml">
|
||||||
|
<form string="Location Quantity">
|
||||||
|
<group>
|
||||||
|
<field name="product_id" readonly='1'/>
|
||||||
|
<field name="qty" readonly='1'/>
|
||||||
|
</group>
|
||||||
|
<group string='Location Products'>
|
||||||
|
<field name="location_lines" nolabel="1" readonly="1">
|
||||||
|
<tree>
|
||||||
|
<field name="location_id"/>
|
||||||
|
<field name="quantity"/>
|
||||||
|
<field name="company_id"/>
|
||||||
|
</tree>
|
||||||
|
</field>
|
||||||
|
</group>
|
||||||
|
<footer>
|
||||||
|
<button string="Cancel" class="btn-default" special="cancel"/>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
<record id="action_stock_location_quantity" model="ir.actions.act_window">
|
||||||
|
<field name="name">Location Quantity</field>
|
||||||
|
<field name="type">ir.actions.act_window</field>
|
||||||
|
<field name="res_model">stock.location.quantity</field>
|
||||||
|
<field name="view_mode">form</field>
|
||||||
|
<field name="view_id" ref="view_stock_location_quantity_form"/>
|
||||||
|
<field name="target">new</field>
|
||||||
|
</record>
|
||||||
|
|
||||||
|
</odoo>
|
||||||
Reference in New Issue
Block a user