commit
4bdcc9e27c
|
|
@ -1,3 +1,33 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<!-- Placeholder for future email templates and activities -->
|
||||
<data noupdate="1">
|
||||
<record id="email_template_annual_rfq_ar" model="mail.template">
|
||||
<field name="name">Purchase Order: Send RFQ</field>
|
||||
<field name="model_id" ref="odex25_annual_purchase.model_annual_rfq"/>
|
||||
<field name="subject">طلب عرض سعر ${object.name or ''}</field>
|
||||
<field name="body_html" type="html">
|
||||
<div style="margin: 0px; padding: 0px;">
|
||||
<p style="margin: 0px; padding: 0px; font-size: 13px; font-family: Arial, sans-serif; direction: rtl; text-align: right;">
|
||||
عزيزي ${object.vendor_id.name}
|
||||
% if object.vendor_id.parent_id:
|
||||
(${object.vendor_id.parent_id.name})
|
||||
% endif
|
||||
<br/><br/>
|
||||
يُرفق إليكم طلب عرض السعر الخاص بالطلب رقم <strong>${object.name}</strong>
|
||||
% if object.partner_ref:
|
||||
بالمرجع: ${object.partner_ref}
|
||||
% endif
|
||||
من شركة ${object.company_id.name}.
|
||||
<br/><br/>
|
||||
في حال وجود أي استفسارات، لا تترددوا في التواصل معنا.
|
||||
<br/><br/>
|
||||
مع أطيب التحيات،
|
||||
</p>
|
||||
</div></field>
|
||||
<field name="report_template" ref="odex25_annual_purchase.action_report_annual_rfq"/>
|
||||
<field name="report_name">${(object.name or '').replace('/','_')}</field>
|
||||
<field name="lang">ar</field>
|
||||
<field name="auto_delete" eval="True"/>
|
||||
</record>
|
||||
</data>
|
||||
</odoo>
|
||||
|
|
|
|||
|
|
@ -173,11 +173,7 @@ msgstr "عدد المرفقات"
|
|||
msgid "Can Create Agreement"
|
||||
msgstr "يمكن إنشاء اتفاقية"
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_odx_annual_addendum_form
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_odx_annual_request_form
|
||||
msgid "Cancel"
|
||||
msgstr "إلغاء"
|
||||
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model:ir.model.fields.selection,name:odex25_annual_purchase.selection__odx_annual_addendum__state__cancel
|
||||
|
|
@ -1042,15 +1038,6 @@ msgstr "هل أنت متأكد أنك تريد المتابعة؟"
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: code:addons/odex25_annual_purchase/models/annual_rfq.py:0
|
||||
#: model:ir.model,name:odex25_annual_purchase.model_annual_rfq
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_annual_rfq_form
|
||||
#, python-format
|
||||
msgid "Request for Quotation"
|
||||
msgstr "طلب عرض سعر"
|
||||
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
|
|
@ -1274,3 +1261,34 @@ msgstr "تأكيد"
|
|||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_odx_annual_request_reason_wizard_form
|
||||
msgid "Discard"
|
||||
msgstr "إلغاء"
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: code:addons/odex25_annual_purchase/models/annual_rfq.py:0
|
||||
#: model:ir.model,name:odex25_annual_purchase.model_annual_rfq
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_annual_rfq_form
|
||||
#, python-format
|
||||
msgid "Request for Quotation"
|
||||
msgstr "طلب عرض سعر"
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_refuse_reason_rfq_form
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_select_reason_rfq_form
|
||||
msgid "Submit"
|
||||
msgstr "إرسال"
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model:ir.model.fields.selection,name:odex25_annual_purchase.selection__odx_annual_request_reason_wizard__action_type__cancel
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_odx_annual_addendum_form
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_odx_annual_request_form
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_refuse_reason_rfq_form
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_select_reason_rfq_form
|
||||
msgid "Cancel"
|
||||
msgstr "إلغاء"
|
||||
|
||||
#. module: odex25_annual_purchase
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_annual_purchase.view_annual_rfq_form
|
||||
msgid "Re-Send by Email"
|
||||
msgstr "إعادة إرسال طلب عرض سعر"
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ class AnnualPurchaseRequest(models.Model):
|
|||
vendor_id = fields.Many2one('res.partner', string="Selected Vendor", domain=[('supplier_rank','>',0)])
|
||||
currency_id = fields.Many2one('res.currency', string="Currency", default=lambda self: self.env.company.currency_id.id)
|
||||
technical_notes = fields.Html(string="Technical Notes")
|
||||
financial_notes = fields.Html(string="Financial Notes", groups="purchase_requisition_custom.committe_member")
|
||||
financial_notes = fields.Html(string="Financial Notes")
|
||||
committee_recommended_vendor_id = fields.Many2one('res.partner', string="Recommended Vendor", domain=[('supplier_rank','>',0)])
|
||||
committee_status = fields.Selection([
|
||||
('none','None'),
|
||||
|
|
@ -379,8 +379,6 @@ class AnnualPurchaseRequest(models.Model):
|
|||
def action_create_agreement(self):
|
||||
for rec in self:
|
||||
rec._check_lines()
|
||||
if not rec.vendor_id:
|
||||
raise UserError(_("Please set Selected Vendor."))
|
||||
if rec.agreement_id:
|
||||
raise UserError(_("Agreement already linked."))
|
||||
agreement = self.env['purchase.requisition'].create({
|
||||
|
|
@ -406,6 +404,9 @@ class AnnualPurchaseRequest(models.Model):
|
|||
rec.message_post(body=_("Purchase Agreement created and linked."))
|
||||
self.write({'state':'approved'})
|
||||
|
||||
|
||||
|
||||
|
||||
class AnnualPurchaseRequestLine(models.Model):
|
||||
_name = "odx.annual.request.line"
|
||||
_description = "Annual Purchase Request Line"
|
||||
|
|
|
|||
|
|
@ -15,7 +15,6 @@ class PurchaseRFQ(models.Model):
|
|||
vendor_id = fields.Many2one(
|
||||
'res.partner',
|
||||
string='Vendor',
|
||||
domain=[('supplier_rank', '>', 0)]
|
||||
)
|
||||
partner_id = fields.Many2one(
|
||||
'res.partner',
|
||||
|
|
@ -120,20 +119,37 @@ class PurchaseRFQ(models.Model):
|
|||
|
||||
def action_refuse_rfq(self):
|
||||
self.ensure_one()
|
||||
member = self._get_current_member_vote()
|
||||
member = self.committe_members.filtered(lambda m: m.user_id == self.env.user)
|
||||
|
||||
if member and member.refused:
|
||||
raise UserError(_("You have already refused this RFQ before."))
|
||||
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': _('Refuse Reason'),
|
||||
'res_model': 'refuse.reason.rfq',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_rfq_id': self.id
|
||||
}
|
||||
}
|
||||
|
||||
else:
|
||||
self.env['committe.member'].create({
|
||||
'rfq_id': self.id,
|
||||
'user_id': self.env.user.id,
|
||||
'refused': True,
|
||||
'select': False
|
||||
})
|
||||
|
||||
self._check_committee_rejection()
|
||||
|
||||
def _check_committee_rejection(self):
|
||||
self.ensure_one()
|
||||
|
||||
if not self.source_request_ref or not self.source_request_ref.committe_members:
|
||||
return
|
||||
|
||||
requisition_users = self.source_request_ref.committe_members
|
||||
rfq_users = self.committe_members.mapped('user_id')
|
||||
|
||||
if set(requisition_users.ids) == set(rfq_users.ids):
|
||||
if self.committe_members and all(member.refused for member in self.committe_members):
|
||||
self.source_request_ref.write({'state': 'rejected_by_committee'})
|
||||
self.action_reject()
|
||||
self.message_post(body=_("تم رفض عرض السعر من قبل جميع أعضاء اللجنة."))
|
||||
|
||||
|
||||
def action_submit_to_committees(self):
|
||||
res = super(PurchaseRFQ, self).action_submit_to_committees()
|
||||
|
|
@ -168,6 +184,19 @@ class PurchaseRFQ(models.Model):
|
|||
'target': 'current',
|
||||
}
|
||||
|
||||
def write(self, vals):
|
||||
res = super().write(vals)
|
||||
if 'state' in vals:
|
||||
for rec in self:
|
||||
if rec.state in ['po', 'approved']:
|
||||
related_rfqs = self.search([
|
||||
('source_request_ref', '=', rec.source_request_ref.id),
|
||||
('id', '!=', rec.id),
|
||||
('state', 'not in', ['po', 'approved', 'rejected'])
|
||||
])
|
||||
related_rfqs.write({'state': 'rejected'})
|
||||
return res
|
||||
|
||||
def action_rfq_send(self):
|
||||
self.ensure_one()
|
||||
if not self.vendor_id:
|
||||
|
|
@ -176,7 +205,7 @@ class PurchaseRFQ(models.Model):
|
|||
self.partner_id = self.vendor_id.id
|
||||
|
||||
try:
|
||||
template = self.env.ref('odex25_annual_purchase.email_template_annual_rfq')
|
||||
template = self.env.ref('odex25_annual_purchase.email_template_annual_rfq_ar')
|
||||
except ValueError:
|
||||
template = False
|
||||
|
||||
|
|
@ -209,7 +238,6 @@ class PurchaseRFQ(models.Model):
|
|||
|
||||
ctx['model_description'] = _('Request for Quotation')
|
||||
|
||||
self.state ='sent'
|
||||
return {
|
||||
'name': _('Compose Email'),
|
||||
'type': 'ir.actions.act_window',
|
||||
|
|
@ -233,8 +261,8 @@ class PurchaseRFQ(models.Model):
|
|||
if any((l.quantity or 0.0) <= 0.0 for l in self.line_ids):
|
||||
raise UserError(_('ضروري الكمية تكون أكبر من 0.'))
|
||||
|
||||
if any((l.price_unit or 0.0) <= 0.0 for l in self.line_ids):
|
||||
raise UserError(_('رجاء أضِف الأسعار لكل السطور.'))
|
||||
# if any((l.price_unit or 0.0) <= 0.0 for l in self.line_ids):
|
||||
# raise UserError(_('رجاء أضِف الأسعار لكل السطور.'))
|
||||
|
||||
def _sync_approved_prices_to_request(self):
|
||||
|
||||
|
|
@ -318,6 +346,18 @@ class PurchaseRFQ(models.Model):
|
|||
rec.state = 'rejected'
|
||||
|
||||
|
||||
|
||||
class MailComposeMessage(models.TransientModel):
|
||||
_inherit = 'mail.compose.message'
|
||||
|
||||
def send_mail(self, auto_commit=False):
|
||||
res = super(MailComposeMessage, self).send_mail(auto_commit=auto_commit)
|
||||
if self.model == 'annual.rfq' and self.res_id:
|
||||
rfq = self.env['annual.rfq'].browse(self.res_id)
|
||||
rfq.write({'state': 'sent'})
|
||||
return res
|
||||
|
||||
|
||||
class PurchaseRFQLine(models.Model):
|
||||
_name = 'annual.rfq.line'
|
||||
_description = 'RFQ Line Items'
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
access_request_staff,access_request_staff,model_odx_annual_request,purchase.group_purchase_user,1,1,1,0
|
||||
access_request_manager,access_request_manager,model_odx_annual_request,purchase.group_purchase_manager,1,1,1,0
|
||||
access_request_manager,access_request_manager,model_odx_annual_request,purchase.group_purchase_manager,1,1,0,0
|
||||
access_request_committee,access_request_committee,model_odx_annual_request,purchase_requisition_custom.committe_member,1,0,0,0
|
||||
access_request_ssd,access_request_ssd,model_odx_annual_request,hr_base.group_services_manager,1,1,0,0
|
||||
access_request_gm,access_request_gm,model_odx_annual_request,hr_base.group_general_manager,1,1,0,0
|
||||
|
|
|
|||
|
|
|
@ -23,6 +23,7 @@
|
|||
<form string="Annual Purchase Request">
|
||||
<header>
|
||||
<field name="can_create_agreement" invisible="1"/>
|
||||
|
||||
<button name="action_send" string="Send" type="object" states="draft" class="btn-primary" groups="purchase.group_purchase_user" icon="fa-send"/>
|
||||
<button name="action_manager_approve" string="Approve" type="object" class="btn-primary" states="to_manager" groups="purchase.group_purchase_manager" icon="fa-check-circle"/>
|
||||
<button name="action_manager_reject" string="Reject" type="object" states="to_manager" groups="purchase.group_purchase_manager" class="btn-danger" icon="fa-times-circle"/>
|
||||
|
|
@ -35,9 +36,10 @@
|
|||
<button name="action_ceo_reject" string="Reject" type="object" states="ceo" groups="hr_base.group_general_manager" class="btn-danger" icon="fa-times-circle"/>
|
||||
<button name="action_create_agreement" string="Create Agreement" type="object" states="purchase" class="btn-primary" groups="purchase.group_purchase_manager" icon="fa-file-contract"/>
|
||||
<button name="action_to_draft" string="Back To Draft" type="object" states="rejected" class="btn-secondary" groups="odex25_annual_purchase.group_annual_to_draft" icon="fa-undo" />
|
||||
|
||||
<field name="state" widget="statusbar" statusbar_visible="draft,to_manager,procurement,committee,ssd,ceo,approved,rejected,cancel"/>
|
||||
</header>
|
||||
<sheet>
|
||||
<sheet attrs="{'readonly': [('state', '!=', 'draft')]}">
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button class="oe_stat_button" type="object" name="action_open_rfqs" icon="fa-list-alt">
|
||||
<field name="rfq_count" widget="statinfo" string="RFQs"/>
|
||||
|
|
@ -71,35 +73,35 @@
|
|||
|
||||
<group>
|
||||
<field name="sent_to_commitee" invisible="1"/>
|
||||
<field name="department_id"/>
|
||||
<field name="product_category_ids" widget="many2many_tags"/>
|
||||
<field name="date"/>
|
||||
<field name="ssd_approve"/>
|
||||
<field name="seo_approve"/>
|
||||
<field name="department_id" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="product_category_ids" widget="many2many_tags" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="date" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="ssd_approve" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="seo_approve" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
|
||||
</group>
|
||||
<group>
|
||||
<group attrs="{'readonly': [('state', '!=', 'draft')]}">
|
||||
<field name="employee_id" readonly="1"/>
|
||||
<field name="user_id" invisible="1"/>
|
||||
<field name="purpose"/>
|
||||
<field name="purpose" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
<field name="date_start" invisible="1"/>
|
||||
<field name="date_end" invisible="1"/>
|
||||
<field name="vendor_id" invisible="1"/>
|
||||
<field name="committee_enabled"/>
|
||||
<field name="committee_enabled" attrs="{'readonly': [('state', '!=', 'draft')]}"/>
|
||||
|
||||
<field name="committee_type_id"
|
||||
attrs="{'invisible': [('committee_enabled', '=', False)], 'required': [('committee_enabled', '=', True)]}"/>
|
||||
attrs="{'invisible': [('committee_enabled', '=', False)], 'required': [('committee_enabled', '=', True)],'readonly': [('state', '!=', 'draft')] }"/>
|
||||
|
||||
<field name="committe_head"
|
||||
attrs="{'invisible': [('committee_enabled', '=', False)], 'required': [('committee_enabled', '=', True)]}"/>
|
||||
attrs="{'invisible': [('committee_enabled', '=', False)], 'required': [('committee_enabled', '=', True)],'readonly': [('state', '!=', 'draft')] }"/>
|
||||
|
||||
<field name="agreement_id" invisible="1"/>
|
||||
|
||||
<field name="min_approve"
|
||||
attrs="{'invisible': [('committee_enabled', '=', False)], 'required': [('committee_enabled', '=', True)]}"/>
|
||||
attrs="{'invisible': [('committee_enabled', '=', False)], 'required': [('committee_enabled', '=', True)],'readonly': [('state', '!=', 'draft')] }"/>
|
||||
|
||||
<field name="min_vote"
|
||||
attrs="{'invisible': [('committee_enabled', '=', False)], 'required': [('committee_enabled', '=', True)]}"/>
|
||||
attrs="{'invisible': [('committee_enabled', '=', False)], 'required': [('committee_enabled', '=', True)],'readonly': [('state', '!=', 'draft')] }"/>
|
||||
|
||||
</group>
|
||||
|
||||
|
|
@ -107,7 +109,7 @@
|
|||
</group>
|
||||
<notebook>
|
||||
<page string="Products">
|
||||
<field name="line_ids">
|
||||
<field name="line_ids" attrs="{'readonly': [('state', '!=', 'draft')]}">
|
||||
<tree editable="bottom" delete="true">
|
||||
<field name="product_id"/>
|
||||
<field name="description"/>
|
||||
|
|
@ -121,7 +123,7 @@
|
|||
|
||||
<page string="Description">
|
||||
<group>
|
||||
<field name="description"/>
|
||||
<field name="description" attrs="{'readonly': [('state', '!=', 'draft')]}" />
|
||||
</group>
|
||||
|
||||
</page>
|
||||
|
|
@ -129,7 +131,7 @@
|
|||
<page string="Committee " attrs="{'invisible': [('committee_enabled', '=', False)]}">
|
||||
<group>
|
||||
<field name="committe_members"
|
||||
attrs="{'required': [('committee_enabled', '=', True)]}">
|
||||
attrs="{'required': [('committee_enabled', '=', True)],'readonly': [('state', '!=', 'draft')] }">
|
||||
<tree>
|
||||
<field name="name"/>
|
||||
</tree>
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
class="btn-primary"
|
||||
attrs="{'invisible': [('state', 'not in', ['sent','draft'])]}"
|
||||
/>
|
||||
<button name="action_rfq_send" states="sent" string="Re-Send by Email" type="object" context="{'send_rfq':True}"/>
|
||||
|
||||
|
||||
<button name="action_select_rfq"
|
||||
type="object"
|
||||
|
|
@ -60,7 +62,7 @@
|
|||
</button>
|
||||
</div>
|
||||
<div class="oe_title">
|
||||
<span class="o_form_label" >Request for Quotation</span>
|
||||
<span class="o_form_label" >طلب عرض سعر</span>
|
||||
<h1>
|
||||
<!-- <field name="priority" widget="priority" class="mr-3"/>-->
|
||||
<field name="name" readonly="1"/>
|
||||
|
|
@ -111,7 +113,7 @@
|
|||
<div class="oe_clear"/>
|
||||
</page>
|
||||
<page id="page_committee_members" string="Committe Members"
|
||||
groups="odex25_annual_purchase.group_technical_committee,odex25_annual_purchase.group_annual_committee"
|
||||
groups="odex25_annual_purchase.group_technical_committee,odex25_annual_purchase.group_annual_committee,purchase.group_purchase_user"
|
||||
>
|
||||
<field name="committe_members">
|
||||
<tree>
|
||||
|
|
@ -186,7 +188,7 @@
|
|||
<field name="recommendation_order" />
|
||||
<field name="vendor_id"/>
|
||||
<field name="request_date"/>
|
||||
<field name="amount_total"/>
|
||||
<field name="amount_total" groups="hr_base.group_general_manager,hr_base.group_services_manager,purchase.group_purchase_user,purchase.group_purchase_manager,odex25_annual_purchase.group_annual_committee"/>
|
||||
<field name="state"/>
|
||||
</tree>
|
||||
</field>
|
||||
|
|
|
|||
Loading…
Reference in New Issue