Browse Source

Nov 17 [UPDT] : Bug Fixed 'account_payment_approval'

pull/232/head
AjmalCybro 3 years ago
parent
commit
19c5cefce7
  1. 3
      account_payment_approval/__manifest__.py
  2. 2
      account_payment_approval/models/__init__.py
  3. 117
      account_payment_approval/models/account_payment.py
  4. 36
      account_payment_approval/models/payment_approvers.py
  5. 12
      account_payment_approval/models/res_config_settings.py
  6. 2
      account_payment_approval/security/ir.model.access.csv
  7. BIN
      account_payment_approval/static/description/images/configure.png
  8. BIN
      account_payment_approval/static/description/images/multi.png
  9. BIN
      account_payment_approval/static/description/images/payment-approval-03.png
  10. BIN
      account_payment_approval/static/description/images/payment-approval-04.png
  11. BIN
      account_payment_approval/static/description/images/payment-approval-05.png
  12. BIN
      account_payment_approval/static/description/images/single.png
  13. 143
      account_payment_approval/static/description/index.html
  14. 10
      account_payment_approval/views/account_payment_view.xml
  15. 24
      account_payment_approval/views/payment_approvers.xml
  16. 32
      account_payment_approval/views/res_config_settings_views.xml

3
account_payment_approval/__manifest__.py

@ -32,7 +32,10 @@
'website': "https://www.cybrosys.com",
'depends': ['account'],
'data': [
'security/ir.model.access.csv',
'views/payment_approvers.xml',
'views/res_config_settings_views.xml',
'views/account_payment_view.xml',
],
'license': 'LGPL-3',

2
account_payment_approval/models/__init__.py

@ -22,3 +22,5 @@
from . import account_payment
from . import res_config_settings
from . import payment_approvers

117
account_payment_approval/models/account_payment.py

@ -36,32 +36,73 @@ class AccountMove(models.Model):
class AccountPayment(models.Model):
_inherit = "account.payment"
_inherits = {'account.move': 'move_id'}
# _inherits = {'account.move': 'move_id'}
def _check_is_approver(self):
approval = self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.payment_approval')
approver_id = int(self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.approval_user_id'))
self.is_approver = True if self.env.user.id == approver_id and approval else False
if self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.multi_approval'):
approval = self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.multi_approval')
print(approval, 'nn')
approver_id = self.env['payment.approves'].search([],order='amount')
print(approver_id, 'vvvvv')
for rec in approver_id:
print(rec.approve_user_id,'approve_user_id')
if rec.approve_user_id.id == self.env.user.id:
self.is_approver_check = True
else:
self.is_approver_check = False
if self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.payment_approval'):
approval = self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.payment_approval')
approver_id = int(self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.approval_user_id'))
self.is_approver_check = True if self.env.user.id == approver_id and approval else False
is_approver_check = fields.Boolean(compute=_check_is_approver, readonly=True)
is_approver = fields.Boolean(compute=_check_is_approver, readonly=True)
is_approver = fields.Boolean()
def action_post(self):
"""Overwrites the _post() to validate the payment in the 'approved' stage too.
Currently Odoo allows payment posting only in draft stage.
"""
# Post the payments "normally" if no transactions are needed.
# If not, let the acquirer update the state.
validation = self._check_payment_approval()
if validation:
if validation and self.state:
if self.state not in ('draft', 'approved'):
raise UserError(_("Only a draft or approved payment can be posted."))
if any(inv.state != 'posted' for inv in self.reconciled_invoice_ids):
raise ValidationError(_("The payment cannot be processed because the invoice is not open!"))
self.move_id._post(soft=False)
payments_need_tx = self.filtered(
lambda p: p.payment_token_id and not p.payment_transaction_id
)
# creating the transaction require to access data on payment acquirers, not always accessible to users
# able to create payments
transactions = payments_need_tx.sudo()._create_payment_transaction()
res = super(AccountPayment, self - payments_need_tx).action_post()
for tx in transactions: # Process the transactions with a payment by token
tx._send_payment_request()
# Post payments for issued transactions
transactions._finalize_post_processing()
payments_tx_done = payments_need_tx.filtered(
lambda p: p.payment_transaction_id.state == 'done'
)
super(AccountPayment, payments_tx_done).action_post()
payments_tx_not_done = payments_need_tx.filtered(
lambda p: p.payment_transaction_id.state != 'done'
)
payments_tx_not_done.action_cancel()
return res
def _check_payment_approval(self):
if self.state == "draft":
second_approval = self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.multi_approval')
first_approval = self.env['ir.config_parameter'].sudo().get_param(
'account_payment_approval.payment_approval')
if first_approval:
@ -80,7 +121,48 @@ class AccountPayment(models.Model):
self.write({
'state': 'waiting_approval'
})
self.is_approver = True
return False
if second_approval:
val = self.env['payment.approves'].search([], order='amount').mapped('amount')
approve_payment = self.env['payment.approves'].search([], order='amount')
for x in val:
for rec in approve_payment:
index = val.index(x) + 1
if index ==len(val):
index = index - 1
if self.amount > rec.amount and rec.approve_user_id.id == self.env.user.id:
self.is_approver = True
if self.amount > rec.amount and self.amount <= val[index] :
if rec.approve_user_id.id == self.env.user.id:
self.is_approver = True
payment_amount = self.amount
if rec.approval_currency_id:
if self.currency_id.id != rec.approval_currency_id.id:
currency_id = self.env['res.currency'].browse(rec.approval_currency_id.id)
payment_amount = self.currency_id._convert(
self.amount, currency_id, self.company_id,
self.date or fields.Date.today(), round=True)
if payment_amount > rec.amount:
self.write({
'state': 'waiting_approval'
})
return False
else:
self.is_approver = False
self.write({
'state': 'waiting_approval'
})
return False
elif self.amount < val[0]:
self.is_approver = False
return True
else:
self.write({
'state': 'waiting_approval'
})
self.is_approver = False
return False
return True
def approve_transfer(self):
@ -90,6 +172,7 @@ class AccountPayment(models.Model):
})
def reject_transfer(self):
self.write({
'state': 'rejected'
})
if self.is_approver:
self.write({
'state': 'rejected'
})

36
account_payment_approval/models/payment_approvers.py

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
#############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2021-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Cybrosys Techno Solutions(<https://www.cybrosys.com>)
#
# You can modify it under the terms of the GNU LESSER
# GENERAL PUBLIC LICENSE (LGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU LESSER GENERAL PUBLIC LICENSE (LGPL v3) for more details.
#
# You should have received a copy of the GNU LESSER GENERAL PUBLIC LICENSE
# (LGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
#############################################################################
from odoo import fields, models
class PaymentApprover(models.Model):
_name = 'payment.approves'
approve_user_id = fields.Many2one('res.users','Approver')
amount = fields.Float('Amount',help="If amount is 0.00, All the payments go through approval")
approval_currency_id = fields.Many2one('res.currency', string='Approval Currency',
help="Converts the payment amount to this currency if chosen.")

12
account_payment_approval/models/res_config_settings.py

@ -20,7 +20,7 @@
#
#############################################################################
from odoo import fields, models
from odoo import fields, models, api
class ResConfigSettings(models.TransientModel):
@ -31,7 +31,10 @@ class ResConfigSettings(models.TransientModel):
account_manager_ids = user_ids.filtered(lambda l: l.has_group('account.group_account_manager'))
return [('id', 'in', account_manager_ids.ids)]
payment_approval = fields.Boolean('Payment Approval', config_parameter='account_payment_approval.payment_approval')
payment_approval = fields.Boolean('Single Payment Approval',
config_parameter='account_payment_approval.payment_approval')
multi_approval = fields.Boolean('Multi Payment Approval',
config_parameter='account_payment_approval.multi_approval')
approval_user_id = fields.Many2one('res.users', string="Payment Approver", required=False,
domain=_get_account_manager_ids,
config_parameter='account_payment_approval.approval_user_id')
@ -41,3 +44,8 @@ class ResConfigSettings(models.TransientModel):
approval_currency_id = fields.Many2one('res.currency', string='Approval Currency',
config_parameter='account_payment_approval.approval_currency_id',
help="Converts the payment amount to this currency if chosen.")
@api.onchange('multi_approval')
def onchange_multi_approval(self):
if self.multi_approval:
self.payment_approval = False

2
account_payment_approval/security/ir.model.access.csv

@ -0,0 +1,2 @@
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_payment_approves,payment.approves,model_payment_approves,base.group_user,1,1,1,1
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
2 access_payment_approves payment.approves model_payment_approves base.group_user 1 1 1 1

BIN
account_payment_approval/static/description/images/configure.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
account_payment_approval/static/description/images/multi.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

BIN
account_payment_approval/static/description/images/payment-approval-03.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 62 KiB

BIN
account_payment_approval/static/description/images/payment-approval-04.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 65 KiB

BIN
account_payment_approval/static/description/images/payment-approval-05.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

BIN
account_payment_approval/static/description/images/single.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 114 KiB

143
account_payment_approval/static/description/index.html

@ -14,7 +14,8 @@
</div>
<h2 style="font-weight: 600;font-size: 1.8rem;margin-top: 15px;">Key Highlights</h2>
<ul style=" padding: 0 1px; list-style: none; ">
<li style="display: flex;align-items: center;padding: 8px 0;font-size: 18px;"><i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>Approval stages in payments
<li style="display: flex;align-items: center;padding: 8px 0;font-size: 18px;"><i
class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>Approval stages in payments
</li>
</ul>
</div>
@ -108,7 +109,8 @@
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>
<i class="fa fa-check-circle-o"
style="width:40px; color:#07B700"></i>
Goto <b>Settings</b> and click on <b>Invoicing</b></h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
@ -121,11 +123,12 @@
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>
Enable Payment Approval</h3>
<i class="fa fa-check-circle-o"
style="width:40px; color:#07B700"></i>
Enable Single Payment Approval</h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
src="images/payment-approval-03.png"></div>
src="images/single.png"></div>
</div>
</div>
@ -134,83 +137,91 @@
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>
Fill the fields.</h3>
<i class="fa fa-check-circle-o"
style="width:40px; color:#07B700"></i>
If You want To Enable Multiple Approval Enable Multi Payment
Approval.</h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
src="images/payment-approval-04.png"></div>
src="images/multi.png"></div>
</div>
</div>
<div class="carousel-item" style="min-height: 0px;">
<div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16"
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>
Once the user tries to create a payment, it goes through payment approvals.</h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
src="images/payment-approval-05.png"></div>
<div class="carousel-item" style="min-height: 0px;">
<div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16"
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o"
style="width:40px; color:#07B700"></i>
Configure the
Approval.</h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
src="images/configure.png"></div>
</div>
</div>
</div>
<div class="carousel-item" style="min-height: 0px;">
<div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16"
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o"
style="width:40px; color:#07B700"></i>
Once the user tries to create a payment, it goes through
payment approvals.</h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
src="images/payment-approval-05.png"></div>
</div>
</div>
<div class="carousel-item" style="min-height: 0px;">
<div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16"
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>
Approvar can approve or reject request.</h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
src="images/payment-approval-06.png"></div>
<div class="carousel-item" style="min-height: 0px;">
<div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16"
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o"
style="width:40px; color:#07B700"></i>
Approvar can approve or reject request.</h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
src="images/payment-approval-06.png"></div>
</div>
</div>
</div>
<div class="carousel-item" style="min-height: 0px;">
<div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16"
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o" style="width:40px; color:#07B700"></i>
User will be able to filter the payment records with 'Waiting For Approval', 'Approved' and 'Rejected'.</h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
src="images/payment-approval-07.png"></div>
<div class="carousel-item" style="min-height: 0px;">
<div class="col-xs-12 col-sm-12 col-md-12 mb16 mt16"
style="float: left;">
<h3 class="alert"
style="font-weight:400;color: #091E42;background: #fff;text-align: left;border-radius: 0; font-size: 18px;">
<i class="fa fa-check-circle-o"
style="width:40px; color:#07B700"></i>
User will be able to filter the payment records with
'Waiting For Approval', 'Approved' and 'Rejected'.</h3>
<div style=""><img class="img img-responsive center-block"
style="border-top-left-radius: 10px;border-top-right-radius: 10px;"
src="images/payment-approval-07.png"></div>
</div>
</div>
</div>
</div>
<a class="carousel-control-prev" href="#demo" data-slide="prev"
style="left:-25px;width: 35px;color: #000;"> <span
class="carousel-control-prev-icon"><i class="fa fa-chevron-left"
</div>
<a class="carousel-control-prev" href="#demo" data-slide="prev"
style="left:-25px;width: 35px;color: #000;"> <span
class="carousel-control-prev-icon"><i class="fa fa-chevron-left"
style="font-size:24px"></i></span>
</a> <a class="carousel-control-next" href="#demo" data-slide="next"
style="right:-25px;width: 35px;color: #000;"> <span
class="carousel-control-next-icon"><i class="fa fa-chevron-right"
style="font-size:24px"></i></span>
</a> <a class="carousel-control-next" href="#demo" data-slide="next"
style="right:-25px;width: 35px;color: #000;"> <span
class="carousel-control-next-icon"><i class="fa fa-chevron-right"
style="font-size:24px"></i></span>
</a>
</div>
</a>
</div>
</section>
</div>
</div>
</div>
<!-- <div class="px-3 pt-1 tab-pane fade" id="pills-video" role="tabpanel" aria-labelledby="-->
<!-- pills-home-tab">-->
<!-- &lt;!&ndash; Video&ndash;&gt;-->
<!-- <h2 style="font-weight: 600;text-align: center;width: 100%;">Video</h2>-->
<!-- <hr style="margin-top: 0px;margin-bottom: 2%;border: 0;text-align: center;border-top: 3px solid #d21c22;width: 5%;">-->
<!-- <center>-->
<!-- <p>Website Maintenance Request Demo</p>-->
<!-- &lt;!&ndash;<a href="https://www.youtube.com/watch?v=57QWXrMYe84&feature=youtu.be" target="_blank"> <img src="addon-youtube.png" style="width:80%;"></a>&ndash;&gt;-->
<!-- <div class="s_panel_video" data-video-id="7PFB7FpMFyM?rel=0" style="cursor:pointer;">-->
<!-- <img class="img-fluid s_tooltip_tabs_tooltip_image s_figure_link pb0" src="images/task_timer_youtube.png" alt="Cybrosys Cover Video" style="max-width:100%;">-->
<!-- </div>-->
<!-- </center>-->
<!-- </div>-->
<!-- faq tab-->
<div class="px-2 px-lg-4 pt-3 tab-pane fade" id="pills-contact" role="tabpanel"
aria-labelledby="pills-contact-tab">
<ul class="list-unstyled">

10
account_payment_approval/views/account_payment_view.xml

@ -6,24 +6,30 @@
<field name="inherit_id" ref="account.view_account_payment_form"/>
<field name="arch" type="xml">
<xpath expr="//header//button[@name='action_post']" position="after">
<button name="approve_transfer" string="Approve" type="object"
class="oe_highlight"
attrs="{'invisible': ['|',('is_approver', '=', False),('state', '!=', 'waiting_approval')]}"/>
attrs="{'invisible': ['|',('state', '!=', 'waiting_approval'),('is_approver', '=', False)]}"/>
<button name="reject_transfer" string="Reject" type="object"
class="oe_highlight"
attrs="{'invisible': ['|',('is_approver', '=', False),('state', '!=', 'waiting_approval')]}"/>
attrs="{'invisible': ['|',('state', '!=', 'waiting_approval'),('is_approver', '=', False)]}"/>
</xpath>
<xpath expr="//header//button[@name='action_post']" position="attributes">
<attribute name="states">draft,approved</attribute>
</xpath>
<xpath expr="//header//button[@name='action_cancel']" position="attributes">
<attribute name="attrs">{'invisible': [('state', 'in', ('cancelled', 'posted', 'rejected'))]}
</attribute>
</xpath>
<field name="partner_id" position="after">
<field name="is_approver" invisible="1"/>
</field>
</field>
</record>
<record id="view_account_payment_search_inherit" model="ir.ui.view">

24
account_payment_approval/views/payment_approvers.xml

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="view_payment_approver_tree" model="ir.ui.view">
<field name="name">PaymentApprover</field>
<field name="model">payment.approves</field>
<field name="arch" type="xml">
<tree string="Approver" editable="bottom" create="true" delete="true">
<field name="approve_user_id"/>
<field name="amount"/>
<field name="approval_currency_id"/>
</tree>
</field>
</record>
<record model="ir.actions.act_window" id="action_payment_approver">
<field name="name">Approvers</field>
<field name="res_model">payment.approves</field>
<field name="view_mode">tree</field>
<field name="view_id" ref="view_payment_approver_tree"/>
</record>
</odoo>

32
account_payment_approval/views/res_config_settings_views.xml

@ -13,26 +13,24 @@
<div class="col-12 col-lg-6 o_setting_box" title="Enables approval feature in payments."
groups="account.group_account_manager">
<div class="o_setting_left_pane">
<field name="payment_approval"/>
<field name="payment_approval" attrs="{'invisible':[('multi_approval','=',True)]}"/>
</div>
<div class="o_setting_right_pane">
<div class="o_setting_right_pane" attrs="{'invisible':[('multi_approval','=',True)]}">
<label for="payment_approval"/>
<div class="text-muted">
Enable to bring the approval in the payment.
Only account managers can approve the request.
<div class="text-muted">Enable to bring the approval in the payment. Only account
managers
can approve the request.
</div>
<div class="content-group" attrs="{'invisible': [('payment_approval', '=', False)]}">
<div class="row">
<label string="Approvar" for="approval_user_id"
class="col-lg-3 o_light_label"/>
<label string="Approvar" for="approval_user_id" class="col-lg-3 o_light_label"/>
<field name="approval_user_id"
attrs="{'required': [('payment_approval', '=', True)]}"/>
</div>
</div>
<div class="content-group" attrs="{'invisible': [('payment_approval', '=', False)]}">
<div class="row">
<label string="Amount" for="approval_amount"
class="col-lg-3 o_light_label"/>
<label string="Amount" for="approval_amount" class="col-lg-3 o_light_label"/>
<field name="approval_amount"
attrs="{'required': [('payment_approval', '=', True)]}"/>
</div>
@ -42,6 +40,20 @@
<field name="approval_currency_id"/>
</div>
</div>
</div>
<div class="content-group attrs={'invisible': [('payment_approval', '=', False)]}">
<div class="o_setting_left_pane">
<field name="multi_approval"/>
</div>
<label for="multi_approval"/>
<div class="text-muted">Enable to bring the multi approval in the payment. .
</div>
<div class="mt8" attrs="{'invisible': [('multi_approval', '=', False)]}">
<button type="action" name="%(account_payment_approval.action_payment_approver)d"
string="Configure Approvals" icon="fa-arrow-right" class="btn-link"/>
</div>
</div>
</div>
</div>
@ -49,4 +61,4 @@
</field>
</record>
</data>
</odoo>
</odoo>
Loading…
Cancel
Save