commit
897bbda9c0
|
|
@ -11,6 +11,7 @@
|
|||
"security/ir.model.access.csv",
|
||||
"data/sequence.xml",
|
||||
|
||||
|
||||
"views/annual_request_views.xml",
|
||||
"views/addendum_views.xml",
|
||||
"views/purchase_requisition.xml",
|
||||
|
|
@ -20,6 +21,7 @@
|
|||
"views/annual_rfq_views.xml",
|
||||
"views/report_annual_rfq.xml",
|
||||
"data/mail_template_annual_rfq.xml",
|
||||
'data/mail_direct.xml',
|
||||
"views/select_reason_rfq_views.xml",
|
||||
|
||||
"wizard/annual_cancel_wizard_view.xml"
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data>
|
||||
<record id="email_template_direct_manager_x" model="mail.template">
|
||||
<field name="name">Annual Request - Direct Manager Approval</field>
|
||||
<field name="model_id" ref="odex25_annual_purchase.model_odx_annual_request"/>
|
||||
<field name="subject">Annual Purchase Request #${object.name} - Action Required</field>
|
||||
<field name="body_html" type="html">
|
||||
<div style="margin: 0px; padding: 0px; font-family: Arial, sans-serif;">
|
||||
<p>Dear <strong>${object.employee_id.parent_id.name or 'Manager'}</strong>,</p>
|
||||
<p>You have an <strong>Annual Purchase Request</strong> <a href="${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form"
|
||||
>
|
||||
${object.name}
|
||||
</a> pending your approval:</p>
|
||||
<br/>
|
||||
|
||||
</div>
|
||||
</field>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="lang">${object.employee_id.lang}</field>
|
||||
</record>
|
||||
|
||||
<record id="email_template_purchase_manager" model="mail.template">
|
||||
<field name="name">Annual Request - Purchase Manager Approval</field>
|
||||
<field name="model_id" ref="odex25_annual_purchase.model_odx_annual_request"/>
|
||||
<field name="subject">Annual Purchase Request #${object.name} - Approval Required</field>
|
||||
<field name="body_html" type="html">
|
||||
<div style="margin: 0px; padding: 0px; font-family: Arial, sans-serif;">
|
||||
<p>Dear <strong>Purchase Manager</strong>,</p>
|
||||
<p>You have an <strong>Annual Purchase Request</strong> <a href="${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form"
|
||||
>
|
||||
${object.name}
|
||||
</a> pending your approval:</p>
|
||||
<br/>
|
||||
</div>
|
||||
</field>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="lang">${object.employee_id.lang}</field>
|
||||
</record>
|
||||
|
||||
<record id="email_template_services_manager" model="mail.template">
|
||||
<field name="name">Annual Request - Services Manager Approval</field>
|
||||
<field name="model_id" ref="odex25_annual_purchase.model_odx_annual_request"/>
|
||||
<field name="subject">Annual Purchase Request #${object.name} - SSD Approval Required</field>
|
||||
<field name="body_html" type="html">
|
||||
<div style="margin: 0px; padding: 0px; font-family: Arial, sans-serif;">
|
||||
<p>Dear <strong>Services Manager</strong>,</p>
|
||||
<p>You have an <strong>Annual Purchase Request</strong>
|
||||
<a href="${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form">${object.name}</a>
|
||||
pending your approval:
|
||||
</p>
|
||||
<br/>
|
||||
</div>
|
||||
</field>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="lang">${object.employee_id.lang}</field>
|
||||
</record>
|
||||
|
||||
<record id="email_template_general_manager" model="mail.template">
|
||||
<field name="name">Annual Request - General Manager Approval</field>
|
||||
<field name="model_id" ref="odex25_annual_purchase.model_odx_annual_request"/>
|
||||
<field name="subject">Annual Purchase Request #${object.name} - CEO Approval Required</field>
|
||||
<field name="body_html" type="html">
|
||||
<div style="margin: 0px; padding: 0px; font-family: Arial, sans-serif;">
|
||||
<p>Dear <strong>General Manager</strong>,</p>
|
||||
<p>You have an <strong>Annual Purchase Request</strong>
|
||||
<a href="${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form">${object.name}</a>
|
||||
pending your approval:
|
||||
</p>
|
||||
<br/>
|
||||
</div>
|
||||
</field>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="lang">${object.employee_id.lang}</field>
|
||||
</record>
|
||||
<record id="email_template_committee_members" model="mail.template">
|
||||
<field name="name">Annual Request - Committee Members Notification</field>
|
||||
<field name="model_id" ref="odex25_annual_purchase.model_odx_annual_request"/>
|
||||
<field name="subject">RFQs Created for Request #${object.name} - Please Review</field>
|
||||
<field name="body_html" type="html">
|
||||
<div style="margin: 0px; padding: 0px; font-family: Arial, sans-serif;">
|
||||
<p>Dear <strong>Committee Member</strong>,</p>
|
||||
<p>RFQ requests have been created for Request No.
|
||||
<a href="${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form">${object.name}</a>
|
||||
</p>
|
||||
<p>Please proceed to open and review the technical/financial offers</p>
|
||||
<br/>
|
||||
</div>
|
||||
</field>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
<field name="lang">${object.employee_id.lang}</field>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
@ -1338,3 +1338,116 @@ msgstr ""
|
|||
#: model:mail.template,subject:odex25_annual_purchase.email_template_annual_rfq_new
|
||||
msgid "Request for Quotation ${object.name or ''}"
|
||||
msgstr "طلب عرض سعر ${object.name or ''}"
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model:mail.template,body_html:odex25_annual_purchase.email_template_direct_manager_x
|
||||
msgid ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>Dear <strong>${object.employee_id.parent_id.name or 'Manager'}</strong>,</p>\n"
|
||||
" <p>You have an <strong>Annual Purchase Request</strong> <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">\n"
|
||||
" ${object.name}\n"
|
||||
" </a> pending your approval:</p>\n"
|
||||
" <br/>\n"
|
||||
"\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>عزيزي <strong>${object.employee_id.parent_id.name or 'المدير'}</strong>,</p>\n"
|
||||
" <p>لديك طلب <strong>شراء سنوي</strong> <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">\n"
|
||||
" ${object.name}\n"
|
||||
" </a> بحاجة الى اعتماد:</p>\n"
|
||||
" <br/>\n"
|
||||
"\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model:mail.template,body_html:odex25_annual_purchase.email_template_purchase_manager
|
||||
msgid ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>Dear <strong>Purchase Manager</strong>,</p>\n"
|
||||
" <p>You have an <strong>Annual Purchase Request</strong> <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">\n"
|
||||
" ${object.name}\n"
|
||||
" </a> pending your approval:</p>\n"
|
||||
" <br/>\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>عزيزي <strong>مدير المشتريات</strong>,</p>\n"
|
||||
" <p>لديك طلب <strong>شراء سنوي</strong> <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">\n"
|
||||
" ${object.name}\n"
|
||||
" </a> بحاجة الى اعتماد:</p>\n"
|
||||
" <br/>\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model:mail.template,body_html:odex25_annual_purchase.email_template_services_manager
|
||||
msgid ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>Dear <strong>Services Manager</strong>,</p>\n"
|
||||
" <p>You have an <strong>Annual Purchase Request</strong>\n"
|
||||
" <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">${object.name}</a>\n"
|
||||
" pending your approval:\n"
|
||||
" </p>\n"
|
||||
" <br/>\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>عزيزي <strong>مدير الخدمات</strong>,</p>\n"
|
||||
" <p>لديك طلب <strong>شراء سنوي</strong>\n"
|
||||
" <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">${object.name}</a>\n"
|
||||
" بحاجة الى اعتماد:\n"
|
||||
" </p>\n"
|
||||
" <br/>\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model:mail.template,body_html:odex25_annual_purchase.email_template_general_manager
|
||||
msgid ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>Dear <strong>General Manager</strong>,</p>\n"
|
||||
" <p>You have an <strong>Annual Purchase Request</strong>\n"
|
||||
" <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">${object.name}</a>\n"
|
||||
" pending your approval:\n"
|
||||
" </p>\n"
|
||||
" <br/>\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>عزيزي <strong>المدير التنفيذي</strong>,</p>\n"
|
||||
" <p>لديك طلب <strong>شراء سنوي</strong>\n"
|
||||
" <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">${object.name}</a>\n"
|
||||
" بحاجة الى اعتماد:\n"
|
||||
" </p>\n"
|
||||
" <br/>\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model:mail.template,body_html:odex25_annual_purchase.email_template_committee_members
|
||||
msgid ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>Dear <strong>Committee Member</strong>,</p>\n"
|
||||
" <p>RFQ requests have been created for Request No.\n"
|
||||
" <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">${object.name}</a>\n"
|
||||
" </p>\n"
|
||||
" <p>Please proceed to open and review the technical/financial offers</p>\n"
|
||||
" <br/>\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"<div style=\"margin: 0px; padding: 0px; font-family: Arial, sans-serif;\">\n"
|
||||
" <p>عزيزي <strong>عضو اللجنة</strong>,</p>\n"
|
||||
" <p>تم إنشاء طلبات RFQ للطلب رقم\n"
|
||||
" <a href=\"${object.get_base_url()}/web#id=${object.id}&model=odx.annual.request&view_type=form\">${object.name}</a>\n"
|
||||
" </p>\n"
|
||||
" <p>يرجى فتح العروض ومراجعة العروض الفنية/المالية</p>\n"
|
||||
" <br/>\n"
|
||||
"</div>\n"
|
||||
" "
|
||||
|
|
|
|||
|
|
@ -299,6 +299,16 @@ class AnnualPurchaseRequest(models.Model):
|
|||
self._check_lines()
|
||||
for rec in self:
|
||||
rec.write({'state': 'to_manager'})
|
||||
manager = rec.sudo().employee_id.parent_id
|
||||
if manager and manager.user_id and manager.user_id.email:
|
||||
try:
|
||||
template = self.env.ref('odex25_annual_purchase.email_template_direct_manager_x')
|
||||
template.send_mail(rec.id, force_send=True)
|
||||
rec.message_post(body=_("Email sent to Direct Manager: %s") % manager.user_id.name)
|
||||
except Exception as e:
|
||||
rec.message_post(body=_("Failed to send email: %s") % str(e))
|
||||
else:
|
||||
rec.message_post(body=_("No direct manager email found"))
|
||||
|
||||
def action_to_draft(self):
|
||||
for rec in self:
|
||||
|
|
@ -308,12 +318,47 @@ class AnnualPurchaseRequest(models.Model):
|
|||
for rec in self:
|
||||
manager = rec.sudo().employee_id.parent_id
|
||||
if manager:
|
||||
if manager.user_id.id == rec.env.uid :
|
||||
rec.write({'state': 'procurement'})
|
||||
else:
|
||||
raise UserError(_("Sorry, The Approval For The Direct Manager '%s' Only !")%(rec.employee_id.parent_id.name))
|
||||
if manager.user_id.id == rec.env.uid:
|
||||
rec.write({'state': 'procurement'})
|
||||
purchase_group = self.env.ref('purchase.group_purchase_manager')
|
||||
managers = self.env['res.users'].search([
|
||||
('groups_id', '=', purchase_group.id),
|
||||
('email', '!=', False)
|
||||
])
|
||||
if managers:
|
||||
try:
|
||||
template = self.env.ref('odex25_annual_purchase.email_template_purchase_manager')
|
||||
first_manager = managers[0]
|
||||
cc_emails = ','.join(managers[1:].mapped('email')) if len(managers) > 1 else ''
|
||||
template.with_context(
|
||||
default_email_to=first_manager.email,
|
||||
default_email_cc=cc_emails
|
||||
).send_mail(rec.id, force_send=True)
|
||||
rec.message_post(body=_("Email sent to %s Purchase Manager(s)") % len(managers))
|
||||
except Exception as e:
|
||||
rec.message_post(body=_("Failed to send email: %s") % str(e))
|
||||
else:
|
||||
raise UserError(
|
||||
_("Sorry, The Approval For The Direct Manager '%s' Only !") % (rec.employee_id.parent_id.name))
|
||||
else:
|
||||
rec.write({'state': 'procurement'})
|
||||
purchase_group = self.env.ref('purchase.group_purchase_manager')
|
||||
managers = self.env['res.users'].search([
|
||||
('groups_id', '=', purchase_group.id),
|
||||
('email', '!=', False)
|
||||
])
|
||||
if managers:
|
||||
try:
|
||||
template = self.env.ref('odex25_annual_purchase.email_template_purchase_manager')
|
||||
first_manager = managers[0]
|
||||
cc_emails = ','.join(managers[1:].mapped('email')) if len(managers) > 1 else ''
|
||||
template.with_context(
|
||||
default_email_to=first_manager.email,
|
||||
default_email_cc=cc_emails
|
||||
).send_mail(rec.id, force_send=True)
|
||||
rec.message_post(body=_("Email sent to %s Purchase Manager(s)") % len(managers))
|
||||
except Exception as e:
|
||||
rec.message_post(body=_("Failed to send email: %s") % str(e))
|
||||
|
||||
def action_manager_reject(self):
|
||||
self.ensure_one()
|
||||
|
|
@ -334,11 +379,27 @@ class AnnualPurchaseRequest(models.Model):
|
|||
'sent_to_commitee': True,
|
||||
'state': 'committee'
|
||||
})
|
||||
|
||||
rec.rfq_ids.write({'state': 'committee'})
|
||||
|
||||
template = self.env.ref('odex25_annual_purchase.email_template_committee_members')
|
||||
sent_count = 0
|
||||
|
||||
for member in rec.committe_members:
|
||||
if member.email:
|
||||
try:
|
||||
template.with_context(
|
||||
default_email_to=member.email
|
||||
).send_mail(rec.id, force_send=True)
|
||||
sent_count += 1
|
||||
except Exception as e:
|
||||
rec.message_post(body=_("Failed to send to %s: %s") % (member.name, str(e)))
|
||||
|
||||
rec.message_post(
|
||||
body=_("Emails sent to %s/%s committee members") % (sent_count, len(rec.committe_members)))
|
||||
|
||||
else:
|
||||
raise UserError("لا يمكن الإرسال إلى اللجنة لأن عدد RFQs يساوي صفر.")
|
||||
|
||||
def action_send_to_ssd(self):
|
||||
self.write({'state':'ssd'})
|
||||
|
||||
|
|
@ -354,7 +415,24 @@ class AnnualPurchaseRequest(models.Model):
|
|||
|
||||
def action_ssd_approve(self):
|
||||
if self.seo_approve:
|
||||
self.write({'state':'ceo'})
|
||||
self.write({'state': 'ceo'})
|
||||
gm_group = self.env.ref('hr_base.group_general_manager')
|
||||
managers = self.env['res.users'].search([
|
||||
('groups_id', '=', gm_group.id),
|
||||
('email', '!=', False)
|
||||
])
|
||||
if managers:
|
||||
try:
|
||||
template = self.env.ref('odex25_annual_purchase.email_template_general_manager')
|
||||
first_manager = managers[0]
|
||||
cc_emails = ','.join(managers[1:].mapped('email')) if len(managers) > 1 else ''
|
||||
template.with_context(
|
||||
default_email_to=first_manager.email,
|
||||
default_email_cc=cc_emails
|
||||
).send_mail(self.id, force_send=True)
|
||||
self.message_post(body=_("Email sent to %s General Manager(s)") % len(managers))
|
||||
except Exception as e:
|
||||
self.message_post(body=_("Failed to send email: %s") % str(e))
|
||||
else:
|
||||
self.write({'state': 'purchase'})
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ class PurchaseRFQ(models.Model):
|
|||
_name = 'annual.rfq'
|
||||
_description = 'Request for Quotation'
|
||||
_inherit = ['mail.thread', 'mail.activity.mixin']
|
||||
_copy = False # تعطيل النسخ لحجب زر الاستنساخ
|
||||
_copy = False
|
||||
|
||||
|
||||
name = fields.Char(string='Reference Number', default='New', copy=False, tracking=True)
|
||||
|
|
@ -412,10 +412,11 @@ class PurchaseRFQ(models.Model):
|
|||
|
||||
}
|
||||
rline.write(vals)
|
||||
|
||||
def action_sign_rfq(self):
|
||||
for rec in self:
|
||||
rec._validate_lines_simple()
|
||||
if self.source_request_ref.committee_enabled and self.no_of_approve < self.source_request_ref.min_approve:
|
||||
if rec.source_request_ref.committee_enabled and rec.no_of_approve < rec.source_request_ref.min_approve:
|
||||
raise ValidationError(
|
||||
_("Sorry You cannot sign this quotation ,YOU NEED MORE COMMITTE MEMBERS TO choose it"))
|
||||
|
||||
|
|
@ -424,8 +425,44 @@ class PurchaseRFQ(models.Model):
|
|||
rec.state = 'po'
|
||||
if rec.source_request_ref.ssd_approve:
|
||||
rec.source_request_ref.state = 'ssd'
|
||||
services_group = self.env.ref('hr_base.group_services_manager')
|
||||
managers = self.env['res.users'].search([
|
||||
('groups_id', '=', services_group.id),
|
||||
('email', '!=', False)
|
||||
])
|
||||
if managers:
|
||||
try:
|
||||
template = self.env.ref('odex25_annual_purchase.email_template_services_manager')
|
||||
first_manager = managers[0]
|
||||
cc_emails = ','.join(managers[1:].mapped('email')) if len(managers) > 1 else ''
|
||||
template.with_context(
|
||||
default_email_to=first_manager.email,
|
||||
default_email_cc=cc_emails
|
||||
).send_mail(rec.source_request_ref.id, force_send=True)
|
||||
rec.source_request_ref.message_post(
|
||||
body=_("Email sent to %s Services Manager(s)") % len(managers))
|
||||
except Exception as e:
|
||||
rec.source_request_ref.message_post(body=_("Failed to send email: %s") % str(e))
|
||||
elif rec.source_request_ref.seo_approve:
|
||||
rec.source_request_ref.state = 'ceo'
|
||||
gm_group = self.env.ref('hr_base.group_general_manager')
|
||||
managers = self.env['res.users'].search([
|
||||
('groups_id', '=', gm_group.id),
|
||||
('email', '!=', False)
|
||||
])
|
||||
if managers:
|
||||
try:
|
||||
template = self.env.ref('odex25_annual_purchase.email_template_general_manager')
|
||||
first_manager = managers[0]
|
||||
cc_emails = ','.join(managers[1:].mapped('email')) if len(managers) > 1 else ''
|
||||
template.with_context(
|
||||
default_email_to=first_manager.email,
|
||||
default_email_cc=cc_emails
|
||||
).send_mail(rec.source_request_ref.id, force_send=True)
|
||||
rec.source_request_ref.message_post(
|
||||
body=_("Email sent to %s General Manager(s)") % len(managers))
|
||||
except Exception as e:
|
||||
rec.source_request_ref.message_post(body=_("Failed to send email: %s") % str(e))
|
||||
else:
|
||||
rec.source_request_ref.state = 'purchase'
|
||||
else:
|
||||
|
|
@ -433,9 +470,6 @@ class PurchaseRFQ(models.Model):
|
|||
'Cannot continue: the source document is Approval stage.'
|
||||
))
|
||||
|
||||
|
||||
|
||||
|
||||
@api.depends('line_ids.subtotal', 'line_ids.tax_amount')
|
||||
def _compute_amounts(self):
|
||||
for rec in self:
|
||||
|
|
|
|||
Loading…
Reference in New Issue