coc
This commit is contained in:
parent
fb068b1ffc
commit
15f543fd62
|
|
@ -138,9 +138,11 @@ msgid "Certificates of Completion"
|
|||
msgstr "شهادات الانجاز"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__coc_id
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__coc_id
|
||||
msgid "CoC"
|
||||
msgstr ""
|
||||
msgstr "شهادة إنجاز"
|
||||
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order__coc
|
||||
|
|
@ -413,12 +415,6 @@ msgstr ""
|
|||
msgid "Number of unread messages"
|
||||
msgstr ""
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#, python-format
|
||||
msgid "Only the department manager can approve this CoC."
|
||||
msgstr ""
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_reject_wizard_coc__origin
|
||||
msgid "Origin"
|
||||
|
|
@ -622,12 +618,6 @@ msgstr ""
|
|||
msgid "Website communication history"
|
||||
msgstr ""
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#, python-format
|
||||
msgid "You are not allowed to approve this CoC."
|
||||
msgstr ""
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,help:odex25_purchase_coc.field_purchase_coc__vendor_id
|
||||
msgid "You can find a vendor by its Name, TIN, Email or Internal Reference."
|
||||
|
|
@ -663,11 +653,9 @@ msgid "price"
|
|||
msgstr ""
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#. openerp-web
|
||||
#: code:addons/odex25_purchase_coc/static/src/xml/tender_templates.xml:0
|
||||
#, python-format
|
||||
msgid "product"
|
||||
msgstr ""
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__product_id
|
||||
msgid "Product"
|
||||
msgstr "المنتج"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#. openerp-web
|
||||
|
|
@ -699,13 +687,6 @@ msgid "الكميات الجزئية"
|
|||
msgstr ""
|
||||
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odoo/dev_purchase/odex25_purchase/odex25_purchase_coc/models/models.py:0
|
||||
#, python-format
|
||||
msgid "You must receive at least one product before confirmation."
|
||||
msgstr ".يجب استلام منتج واحد على الأقل قبل التأكيد"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__receiving_meth
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_order_line__receiving_meth
|
||||
|
|
@ -721,4 +702,158 @@ msgstr "كمية"
|
|||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__receiving_meth__percentage
|
||||
msgid "Percentage"
|
||||
msgstr "بنسبة الإنجاز"
|
||||
msgstr "بنسبة الإنجاز"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__work_done_scope
|
||||
msgid "Executed as per scope?"
|
||||
msgstr "هل تم تنفيذ الأعمال حسب نطاق العمل؟"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__work_acceptable
|
||||
msgid "Are works acceptable?"
|
||||
msgstr "هل الأعمال المقدمة مقبولة؟"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc__on_time
|
||||
msgid "Delivered on time?"
|
||||
msgstr "هل تم تنفيذ الأعمال في الوقت المحدد؟"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__on_time__yes
|
||||
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__work_acceptable__yes
|
||||
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__work_done_scope__yes
|
||||
msgid "Yes"
|
||||
msgstr "نعم"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__on_time__no
|
||||
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__work_acceptable__no
|
||||
#: model:ir.model.fields.selection,name:odex25_purchase_coc.selection__purchase_coc__work_done_scope__no
|
||||
msgid "No"
|
||||
msgstr "لا"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__po_line_id
|
||||
msgid "Original PO Line"
|
||||
msgstr " أمر الشراء الأصلي"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__name
|
||||
msgid "Description"
|
||||
msgstr "الوصف"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__product_qty
|
||||
msgid "Ordered Qty"
|
||||
msgstr "الكمية"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__qty_ordered
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
|
||||
msgid "Total Ordered"
|
||||
msgstr "الكمية"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__qty_received_total
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
|
||||
msgid "Previously Received"
|
||||
msgstr "المستلم سابقاً"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__qty_remaining
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
|
||||
msgid "Remaining"
|
||||
msgstr "الكمية المتبقية"
|
||||
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__qty_to_receive
|
||||
#: model_terms:ir.ui.view,arch_db:odex25_purchase_coc.purchase_coc_form
|
||||
msgid "Qty to Receive"
|
||||
msgstr "كمية الإستلام"
|
||||
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__price_unit
|
||||
msgid "Unit Price"
|
||||
msgstr "سعر الوحدة"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__product_uom
|
||||
msgid "Unit of Measure"
|
||||
msgstr "وحدة القياس"
|
||||
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__partner_id
|
||||
msgid "Partner"
|
||||
msgstr "الشريك"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__date_planned
|
||||
msgid "Date "
|
||||
msgstr "تاريخ الإستلام"
|
||||
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_line__sub_price_total
|
||||
msgid "Subtotal"
|
||||
msgstr "الإجمالي الفرعي"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/new_models.py:0
|
||||
#, python-format
|
||||
msgid "You must receive at least one product before confirmation."
|
||||
msgstr ".يجب استلام منتج واحد على الأقل قبل التأكيد"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/new_models.py:0
|
||||
#, python-format
|
||||
msgid "You are not allowed to approve this CoC."
|
||||
msgstr "غير مسموح لك بالموافقة على هذا الـ CoC."
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/new_models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/new_models.py:0
|
||||
#, python-format
|
||||
msgid "Sorry, you are not allowed to confirm this CoC."
|
||||
msgstr "عذرًا، غير مسموح لك بتأكيد هذا الـ CoC."
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: code:addons/odex25_purchase_coc/models/new_models.py:0
|
||||
#, python-format
|
||||
msgid "Received quantity for %s cannot exceed remaining quantity (%.2f)"
|
||||
msgstr "الكمية المستلمة لـ %s لا يمكن أن تتجاوز الكمية المتبقية (%.2f)"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: code:addons/odex25_purchase_coc/models/models.py:0
|
||||
#: code:addons/odex25_purchase_coc/models/new_models.py:0
|
||||
#, python-format
|
||||
msgid "Only the department manager can approve this CoC."
|
||||
msgstr "فقط المدير يمكنه الموافقة على هذا الـ CoC."
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: code:addons/odex25_purchase_coc/models/new_models.py:0
|
||||
#, python-format
|
||||
msgid "You must receive at least one product before approval."
|
||||
msgstr "يجب استلام منتج واحد على الأقل قبل الموافقة."
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__backorder_lines_data
|
||||
msgid "Backorder Lines Data"
|
||||
msgstr "بيانات بنود الطلب المتأخر"
|
||||
|
||||
#. module: odex25_purchase_coc
|
||||
#: model:ir.model.fields,field_description:odex25_purchase_coc.field_purchase_coc_partial_wizard__create_backorder
|
||||
msgid "Create Backorder?"
|
||||
msgstr "إنشاء طلب متأخر؟"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import models
|
||||
from . import new_models
|
||||
|
|
@ -0,0 +1,558 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo import models, fields, api, _
|
||||
from datetime import datetime
|
||||
from odoo.exceptions import ValidationError
|
||||
import json
|
||||
|
||||
class POCustom(models.Model):
|
||||
_inherit = 'purchase.order'
|
||||
|
||||
need_coc = fields.Boolean(string='Need CoC?')
|
||||
coc_id = fields.Many2one(comodel_name='purchase.coc', string='CoC Ref')
|
||||
coc = fields.Boolean(string='CoC Created')
|
||||
coc_created = fields.Boolean('COC Created')
|
||||
coc_ids = fields.One2many(comodel_name='purchase.coc', inverse_name='po_id', string='CoCs')
|
||||
coc_count = fields.Integer(string='Cocs', compute="_compute_coc_count")
|
||||
|
||||
is_manual_receipt_user = fields.Boolean(
|
||||
string='Is Manual Receipt User',
|
||||
compute='_compute_is_manual_receipt_user',
|
||||
store=False
|
||||
)
|
||||
|
||||
|
||||
def _compute_is_manual_receipt_user(self):
|
||||
"""
|
||||
"""
|
||||
for order in self:
|
||||
order.is_manual_receipt_user = self.env.user.has_group('odex25_purchase_coc.group_coc_manual_receipt')
|
||||
print("order.is_manual_receipt_user",order.is_manual_receipt_user)
|
||||
@api.depends('coc_ids')
|
||||
def _compute_coc_count(self):
|
||||
for rec in self:
|
||||
rec.coc_count = self.env['purchase.coc'].search_count([('po_id', '=', rec.id)])
|
||||
|
||||
def button_confirm(self):
|
||||
super_action = super(POCustom, self).button_confirm()
|
||||
service_products = self.order_line.filtered(lambda line: line.product_id.type == "service")
|
||||
if service_products:
|
||||
self.action_create_coc()
|
||||
return super_action
|
||||
|
||||
def action_view_coc(self):
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Certificate Of Completions',
|
||||
'res_model': 'purchase.coc',
|
||||
'view_mode': 'tree,form',
|
||||
'target': 'current',
|
||||
'domain': [('po_id', '=', self.id)],
|
||||
'context': {'create': False}
|
||||
}
|
||||
|
||||
def action_create_coc(self):
|
||||
coc = self.env['purchase.coc'].create({
|
||||
'vendor_id': self.partner_id.id,
|
||||
'date': datetime.today(),
|
||||
'po_id': self.id,
|
||||
'state': 'draft'
|
||||
})
|
||||
|
||||
for po_line in self.order_line.filtered(lambda line: line.product_id.type == 'service'):
|
||||
self.env['purchase.coc.line'].create({
|
||||
'coc_id': coc.id,
|
||||
'po_line_id': po_line.id,
|
||||
'product_id': po_line.product_id.id,
|
||||
'product_qty': po_line.product_qty,
|
||||
'qty_ordered': po_line.product_qty,
|
||||
'qty_received_total': 0.0,
|
||||
'qty_remaining': po_line.product_qty,
|
||||
'price_unit': po_line.price_unit,
|
||||
'product_uom': po_line.product_uom.id,
|
||||
'name': po_line.name,
|
||||
'partner_id':self.partner_id.id,
|
||||
'date_planned':po_line.date_planned,
|
||||
'currency_id': po_line.currency_id.id,
|
||||
'sub_price_total':po_line.price_subtotal,
|
||||
|
||||
})
|
||||
|
||||
self.coc_id = coc.id
|
||||
self.coc_created = True
|
||||
|
||||
def action_create_invoice(self):
|
||||
return super().action_create_invoice()
|
||||
|
||||
|
||||
class PurchaseOrderLine(models.Model):
|
||||
_inherit = 'purchase.order.line'
|
||||
|
||||
qty_history = fields.One2many('purchase.order.line.history', 'po_line_id', string='Qty History')
|
||||
|
||||
@api.depends('product_qty', 'qty_received', 'qty_history')
|
||||
def _compute_qty_remain(self):
|
||||
for rec in self:
|
||||
sum_qty_received = sum(rec.qty_history.mapped('qty_received'))
|
||||
rec.back_qty_remain = rec.product_qty - sum_qty_received
|
||||
|
||||
class PurchaseOrderLineHistory(models.Model):
|
||||
_name = 'purchase.order.line.history'
|
||||
_description = 'Purchase Order Line History'
|
||||
|
||||
po_line_id = fields.Many2one('purchase.order.line', string='PO Line', required=True, ondelete='cascade')
|
||||
coc_id = fields.Many2one('purchase.coc', string='CoC Reference')
|
||||
qty_received = fields.Float(string='Qty Received', required=True)
|
||||
date = fields.Datetime(string='Date', default=fields.Datetime.now)
|
||||
|
||||
class PurchaseCoCLine(models.Model):
|
||||
_name = 'purchase.coc.line'
|
||||
_description = 'Purchase CoC Line'
|
||||
|
||||
coc_id = fields.Many2one('purchase.coc', string='CoC', required=True, ondelete='cascade')
|
||||
po_line_id = fields.Many2one('purchase.order.line', string='Original PO Line', required=True)
|
||||
product_id = fields.Many2one('product.product', string='Product', required=True)
|
||||
name = fields.Text(string='Description', required=True)
|
||||
product_qty = fields.Float(string='Ordered Qty', required=True)
|
||||
qty_ordered = fields.Float(string='Total Ordered', help="الكمية الإجمالية المطلوبة من أمر الشراء")
|
||||
qty_received_total = fields.Float(string='Previously Received', help="المستلم في شهادات سابقة")
|
||||
qty_remaining = fields.Float(string='Remaining', compute='_compute_qty_remaining', store=True)
|
||||
qty_to_receive = fields.Float(string='Qty to Receive', help="الكمية المراد استلامها في هذه الشهادة")
|
||||
qty_percentage = fields.Float(string='%')
|
||||
price_unit = fields.Float(string='Unit Price')
|
||||
product_uom = fields.Many2one('uom.uom', string='Unit of Measure')
|
||||
partner_id = fields.Many2one('res.partner', string='Partner')
|
||||
date_planned = fields.Datetime(string='Date ')
|
||||
receiving_meth = fields.Selection(
|
||||
related='coc_id.receiving_meth',
|
||||
string='Receiving Method',
|
||||
store=False
|
||||
)
|
||||
currency_id = fields.Many2one(
|
||||
'res.currency',
|
||||
string="Currency",
|
||||
required=True,
|
||||
)
|
||||
sub_price_total = fields.Monetary(
|
||||
string="Subtotal",
|
||||
currency_field='currency_id',
|
||||
)
|
||||
show_percentage = fields.Boolean(
|
||||
string="Show Percentage",
|
||||
compute="_compute_show_percentage",
|
||||
store=False
|
||||
)
|
||||
|
||||
@api.depends('coc_id.receiving_meth')
|
||||
def _compute_show_percentage(self):
|
||||
for line in self:
|
||||
line.show_percentage = (line.receiving_meth == 'percentage')
|
||||
|
||||
@api.depends('product_qty', 'qty_received_total')
|
||||
def _compute_qty_remaining(self):
|
||||
for line in self:
|
||||
line.qty_remaining = line.qty_ordered - line.qty_received_total
|
||||
|
||||
@api.onchange('qty_percentage')
|
||||
def _onchange_qty_percentage(self):
|
||||
if self.qty_percentage and self.qty_remaining:
|
||||
self.qty_to_receive = (self.qty_percentage / 100) * self.qty_remaining
|
||||
|
||||
@api.onchange('qty_to_receive')
|
||||
def _onchange_qty_to_receive(self):
|
||||
if self.qty_to_receive and self.qty_remaining:
|
||||
self.qty_percentage = (self.qty_to_receive / self.qty_remaining) * 100
|
||||
|
||||
# @api.constrains('qty_to_receive', 'qty_remaining')
|
||||
# def _check_qty_to_receive(self):
|
||||
# for line in self:
|
||||
# if line.qty_to_receive > line.qty_remaining:
|
||||
# raise ValidationError(
|
||||
# _('Quantity to receive (%.2f) cannot exceed remaining quantity (%.2f) for product %s') %
|
||||
# (line.qty_to_receive, line.qty_remaining, line.product_id.display_name)
|
||||
# )
|
||||
|
||||
class AccountInvoiceCustom(models.Model):
|
||||
_inherit = 'account.move'
|
||||
|
||||
def action_post(self):
|
||||
if self.move_type == 'in_invoice':
|
||||
context = self.env.context
|
||||
po = self.env['purchase.order'].search([('id', '=', context.get('active_id', False))])
|
||||
if po and po.coc_ids.filtered(lambda coc: coc.coc_stage == 'befor_bill_valid' and coc.state != 'approve'):
|
||||
raise ValidationError(_("Sorry You cannot Validate Bill until CoC Created and Approved."))
|
||||
return super(AccountInvoiceCustom, self).action_post()
|
||||
|
||||
def action_confirm(self):
|
||||
if self.move_type == 'in_invoice':
|
||||
context = self.env.context
|
||||
po = self.env['purchase.order'].search([('id', '=', context.get('active_id', False))])
|
||||
if po and po.coc_ids.filtered(lambda coc: coc.coc_stage == 'befor_bill_valid' and coc.state != 'approve'):
|
||||
raise ValidationError(_("Sorry You cannot Validate Bill until CoC Created and Approved."))
|
||||
return super(AccountInvoiceCustom, self).action_confirm()
|
||||
|
||||
def action_register_payment(self):
|
||||
if self.move_type == 'in_invoice':
|
||||
context = self.env.context
|
||||
po = self.env['purchase.order'].search([('id', '=', context.get('active_id', False))])
|
||||
if po and po.coc_ids.filtered(lambda coc: coc.coc_stage == 'before_payment' and coc.state != 'approve'):
|
||||
raise ValidationError(_("Sorry You cannot Pay For This Vendor until CoC Created and Approved."))
|
||||
return super(AccountInvoiceCustom, self).action_register_payment()
|
||||
|
||||
class PurchaseCoC(models.Model):
|
||||
_name = 'purchase.coc'
|
||||
_description = 'Purchase CoC'
|
||||
_inherit = ['mail.thread']
|
||||
|
||||
parent_coc_id = fields.Many2one('purchase.coc', string='Parent CoC', copy=False)
|
||||
name = fields.Char(string='Name', copy=False)
|
||||
coc_stage = fields.Selection(
|
||||
string='CoC Stage',
|
||||
selection=[
|
||||
('before_bill', 'Before Bill'),
|
||||
('befor_bill_valid', 'Before Bill Validation'),
|
||||
('before_payment', 'Before Payment')
|
||||
],
|
||||
default='before_bill',
|
||||
tracking=True,
|
||||
copy=False
|
||||
)
|
||||
po_id = fields.Many2one('purchase.order', string='Po Ref.', tracking=True, required=True)
|
||||
vendor_id = fields.Many2one('res.partner', string='Vendor', related="po_id.partner_id", tracking=True)
|
||||
date = fields.Date(string='Date', tracking=True)
|
||||
note = fields.Text(string='Note', tracking=True)
|
||||
state = fields.Selection(
|
||||
string='State',
|
||||
selection=[
|
||||
('draft', 'Applicant'),
|
||||
('manager', 'Direct Manager'),
|
||||
('approve', 'Approve'),
|
||||
('cancel', 'Reject'),
|
||||
],
|
||||
tracking=True,
|
||||
default='draft',
|
||||
copy=False
|
||||
)
|
||||
receiving_meth = fields.Selection(
|
||||
string='Receiving Method',
|
||||
selection=[
|
||||
('quantity', 'Quantity'),
|
||||
('percentage', 'Percentage'),
|
||||
],
|
||||
default='quantity',
|
||||
copy=False
|
||||
)
|
||||
|
||||
is_backorder = fields.Boolean(string='Is Backorder', default=False, copy=False)
|
||||
coc_line_ids = fields.One2many('purchase.coc.line', 'coc_id', string='CoC Lines')
|
||||
reject_reason = fields.Char(string='Reject Reason', tracking=True)
|
||||
tender_name = fields.Char('Tender Name')
|
||||
attach_no = fields.Integer(string="Documents Count", compute='_compute_attach_no')
|
||||
company_id = fields.Many2one('res.company', default=lambda self: self.env.user.sudo().company_id)
|
||||
is_qty_deducted = fields.Boolean(string="Quantity Deducted", default=False, copy=False)
|
||||
|
||||
work_done_scope = fields.Selection(
|
||||
[('yes', 'Yes'), ('no', 'No')],
|
||||
string='Executed as per scope?',
|
||||
|
||||
)
|
||||
work_done_scope_reason = fields.Char(
|
||||
string='Reason',
|
||||
)
|
||||
|
||||
work_acceptable = fields.Selection(
|
||||
[('yes', 'Yes'), ('no', 'No')],
|
||||
string='Are works acceptable?',
|
||||
|
||||
)
|
||||
work_acceptable_reason = fields.Char(
|
||||
string='Reason',
|
||||
)
|
||||
|
||||
on_time = fields.Selection(
|
||||
[('yes', 'Yes'), ('no', 'No')],
|
||||
string='Delivered on time?',
|
||||
|
||||
)
|
||||
delay_days = fields.Integer(
|
||||
string='Delay Days',
|
||||
)
|
||||
delay_reason = fields.Char(
|
||||
string='Delay Reason',
|
||||
)
|
||||
|
||||
@api.onchange('work_done_scope')
|
||||
def _onchange_work_done_scope(self):
|
||||
if self.work_done_scope == 'yes':
|
||||
self.work_done_scope_reason = False
|
||||
|
||||
@api.onchange('work_acceptable')
|
||||
def _onchange_work_acceptable(self):
|
||||
if self.work_acceptable == 'yes':
|
||||
self.work_acceptable_reason = False
|
||||
|
||||
@api.onchange('on_time')
|
||||
def _onchange_on_time(self):
|
||||
if self.on_time == 'yes':
|
||||
self.delay_days = False
|
||||
self.delay_reason = False
|
||||
|
||||
@api.depends('message_attachment_count')
|
||||
def _compute_attach_no(self):
|
||||
for rec in self:
|
||||
rec.attach_no = rec.message_attachment_count
|
||||
|
||||
def get_attachments(self):
|
||||
self.ensure_one()
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': 'Attachments',
|
||||
'res_model': 'ir.attachment',
|
||||
'view_mode': 'kanban,tree,form',
|
||||
'domain': [('res_model', '=', self._name), ('res_id', '=', self.id)],
|
||||
'context': {'default_res_model': self._name, 'default_res_id': self.id},
|
||||
'target': 'current',
|
||||
}
|
||||
|
||||
@api.model
|
||||
def create(self, vals):
|
||||
res = super(PurchaseCoC, self).create(vals)
|
||||
res.name = self.env['ir.sequence'].next_by_code(self._name) or 'New'
|
||||
return res
|
||||
|
||||
|
||||
def action_manager_reject(self):
|
||||
request = self.po_id.request_id
|
||||
user = self.env.user
|
||||
|
||||
if request:
|
||||
employee = request.employee_id.sudo()
|
||||
if employee.parent_id.user_id.id != user.id:
|
||||
raise ValidationError(_('Sorry, you are not allowed to confirm this CoC.'))
|
||||
else:
|
||||
department_manager = self.po_id.department_id.manager_id.sudo()
|
||||
if department_manager.user_id.id != user.id:
|
||||
raise ValidationError(_('Sorry, you are not allowed to confirm this CoC.'))
|
||||
|
||||
if self.env.context['lang'] in ['ar_SY', 'ar_001']:
|
||||
action_name = 'حدد سبب الرفض'
|
||||
else:
|
||||
action_name = 'Specify Reject Reason'
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': action_name,
|
||||
'res_model': 'reject.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {'default_origin': self.id, 'default_origin_name': self._name}
|
||||
}
|
||||
|
||||
def action_confirm(self):
|
||||
self.ensure_one()
|
||||
user = self.env.user
|
||||
for rec in self:
|
||||
request = rec.po_id.request_id
|
||||
if request:
|
||||
if request.employee_id.parent_id.user_id.id != user.id:
|
||||
raise ValidationError(_('Sorry You are not allowed to Confirm this CoC.'))
|
||||
else:
|
||||
pass
|
||||
|
||||
if not any(line.qty_to_receive > 0 for line in rec.coc_line_ids):
|
||||
raise ValidationError(_('You must receive at least one product before confirmation.'))
|
||||
|
||||
for line in rec.coc_line_ids:
|
||||
if line.qty_to_receive > line.qty_remaining:
|
||||
raise ValidationError(
|
||||
_('Received quantity for %s cannot exceed remaining quantity (%.2f)') %
|
||||
(line.product_id.display_name, line.qty_remaining)
|
||||
)
|
||||
|
||||
manager = None
|
||||
manager_name = None
|
||||
if request and request.employee_id and request.employee_id.coach_id:
|
||||
coach = request.employee_id.sudo().coach_id
|
||||
manager = coach.work_email
|
||||
manager_name = coach.name
|
||||
elif not request and rec.po_id.user_id.id == user.id and user.employee_id and user.employee_id.coach_id:
|
||||
coach = user.employee_id.sudo().coach_id
|
||||
manager = coach.work_email
|
||||
manager_name = coach.name
|
||||
|
||||
if manager:
|
||||
template = self.env.ref('odex25_purchase_coc.email_template_completion_certificate_confirmation')
|
||||
if template:
|
||||
template.with_context(manager_name=manager_name).send_mail(
|
||||
rec.id,
|
||||
force_send=True,
|
||||
email_values={'email_to': manager},
|
||||
)
|
||||
|
||||
rec.write({'state': 'manager'})
|
||||
|
||||
def action_approve(self):
|
||||
self.ensure_one()
|
||||
"""Validate that the current user has permission to approve this CoC."""
|
||||
user = self.env.user
|
||||
po = self.po_id.sudo()
|
||||
request = po.request_id
|
||||
|
||||
|
||||
if not any(line.qty_to_receive > 0 for line in self.coc_line_ids):
|
||||
raise ValidationError(_('You must receive at least one product before approval.'))
|
||||
|
||||
backorder_lines_data = []
|
||||
|
||||
if not self.is_qty_deducted:
|
||||
for line in self.coc_line_ids:
|
||||
self.env['purchase.order.line.history'].create({
|
||||
'po_line_id': line.po_line_id.id,
|
||||
'coc_id': self.id,
|
||||
'qty_received': line.qty_to_receive,
|
||||
'date': fields.Datetime.now()
|
||||
})
|
||||
|
||||
new_qty_received = line.po_line_id.qty_received + line.qty_to_receive
|
||||
line.po_line_id.write({'qty_received': new_qty_received})
|
||||
|
||||
remaining_after = line.qty_remaining - line.qty_to_receive
|
||||
|
||||
if remaining_after > 0.01:
|
||||
backorder_lines_data.append({
|
||||
'po_line_id': line.po_line_id.id,
|
||||
'product_id': line.product_id.id,
|
||||
'name': line.name,
|
||||
'qty_ordered': line.qty_ordered,
|
||||
'product_qty': remaining_after,
|
||||
'qty_received_total': line.qty_received_total + line.qty_to_receive,
|
||||
'price_unit': line.price_unit,
|
||||
'product_uom': line.product_uom.id,
|
||||
'partner_id': line.partner_id.id,
|
||||
'date_planned': line.date_planned,
|
||||
'currency_id': line.currency_id.id,
|
||||
'sub_price_total': line.sub_price_total,
|
||||
})
|
||||
|
||||
self.write({'is_qty_deducted': True})
|
||||
|
||||
else:
|
||||
for line in self.coc_line_ids:
|
||||
remaining_after = line.qty_remaining - line.qty_to_receive
|
||||
if remaining_after > 0.01:
|
||||
backorder_lines_data.append({
|
||||
'po_line_id': line.po_line_id.id,
|
||||
'product_id': line.product_id.id,
|
||||
'name': line.name,
|
||||
'qty_ordered': line.qty_ordered,
|
||||
'product_qty': remaining_after,
|
||||
'qty_received_total': line.qty_received_total + line.qty_to_receive,
|
||||
'price_unit': line.price_unit,
|
||||
'product_uom': line.product_uom.id,
|
||||
'partner_id': line.partner_id.id,
|
||||
'date_planned': line.date_planned,
|
||||
'currency_id': line.currency_id.id,
|
||||
'sub_price_total': line.sub_price_total,
|
||||
})
|
||||
|
||||
if backorder_lines_data:
|
||||
return {
|
||||
'name': _('Partial Receipt Confirmation'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'res_model': 'purchase.coc.partial.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {
|
||||
'default_coc_id': self.id,
|
||||
'default_backorder_lines_data': backorder_lines_data,
|
||||
}
|
||||
}
|
||||
else:
|
||||
self.write({'state': 'approve'})
|
||||
|
||||
def _create_backorder_coc(self, backorder_lines_data):
|
||||
backorder_coc = self.create({
|
||||
'po_id': self.po_id.id,
|
||||
'parent_coc_id': self.id,
|
||||
'is_backorder': True,
|
||||
'date': fields.Date.today(),
|
||||
'coc_stage': self.coc_stage,
|
||||
'receiving_meth': self.receiving_meth,
|
||||
})
|
||||
|
||||
for line_data in backorder_lines_data:
|
||||
self.env['purchase.coc.line'].create({
|
||||
'coc_id': backorder_coc.id,
|
||||
'po_line_id': line_data['po_line_id'],
|
||||
'product_id': line_data['product_id'],
|
||||
'name': line_data['name'],
|
||||
'qty_ordered': line_data['qty_ordered'],
|
||||
'product_qty': line_data['product_qty'],
|
||||
'qty_received_total': line_data['qty_received_total'],
|
||||
'qty_remaining': line_data['product_qty'],
|
||||
'price_unit': line_data['price_unit'],
|
||||
'product_uom': line_data['product_uom'],
|
||||
'partner_id': line_data['partner_id'],
|
||||
'date_planned': line_data['date_planned'],
|
||||
'currency_id': line_data['currency_id'],
|
||||
'sub_price_total': line_data['sub_price_total'],
|
||||
})
|
||||
|
||||
return backorder_coc
|
||||
|
||||
def action_cancel(self):
|
||||
user = self.env.user
|
||||
po = self.po_id.sudo()
|
||||
request = po.request_id
|
||||
|
||||
if request:
|
||||
coach_user = request.employee_id.sudo().coach_id.user_id
|
||||
if coach_user.id != user.id:
|
||||
raise ValidationError(_('Only the department manager can approve this CoC.'))
|
||||
else:
|
||||
dept_manager = self.po_id.department_id.manager_id.sudo()
|
||||
coach_user = dept_manager.coach_id.user_id
|
||||
if coach_user.id != user.id:
|
||||
raise ValidationError(_('You are not allowed to approve this CoC.'))
|
||||
|
||||
if self.env.context['lang'] in ['ar_SY', 'ar_001']:
|
||||
action_name = 'حدد سبب الرفض'
|
||||
else:
|
||||
action_name = 'Specify Reject Reason'
|
||||
return {
|
||||
'type': 'ir.actions.act_window',
|
||||
'name': action_name,
|
||||
'res_model': 'reject.wizard',
|
||||
'view_mode': 'form',
|
||||
'target': 'new',
|
||||
'context': {'default_origin': self.id, 'default_origin_name': self._name}
|
||||
}
|
||||
|
||||
def cancel(self):
|
||||
self.write({
|
||||
'state': 'cancel',
|
||||
'reject_reason': self.env.context.get('reject_reason')
|
||||
})
|
||||
self.po_id.message_post(
|
||||
body=_('CoC %s Rejected By %s. Reject Reason: %s') %
|
||||
(self.name, self.env.user.name, self.reject_reason or 'No reason provided')
|
||||
)
|
||||
|
||||
def action_draft(self):
|
||||
self.write({'state': 'draft'})
|
||||
|
||||
|
||||
class RejectWizardCoC(models.TransientModel):
|
||||
_name = 'reject.wizard.coc'
|
||||
_description = 'Reject Wizard for CoC'
|
||||
|
||||
origin = fields.Integer('Origin ID')
|
||||
reject_reason = fields.Text(string='Reject Reason', required=True)
|
||||
origin_name = fields.Char('Origin Model')
|
||||
|
||||
def action_reject(self):
|
||||
origin_rec = self.env[self.origin_name].sudo().browse(self.origin)
|
||||
if not hasattr(origin_rec, 'cancel'):
|
||||
raise ValidationError(_('This object cannot be rejected'))
|
||||
return origin_rec.with_context({'reject_reason': self.reject_reason}).cancel()
|
||||
|
||||
|
||||
|
|
@ -5,3 +5,4 @@ access_odex25_purchase_coc_odex25_purchase_coc_manager,odex25_purchase_coc.odex2
|
|||
access_purchase_order_line_history,purchase_order_line_history_name,model_purchase_order_line_history,,1,1,1,1
|
||||
access_purchase_coc_partial_wizard,access_purchase_coc_partial_wizard,model_purchase_coc_partial_wizard,base.group_user,1,1,1,1
|
||||
access_purchase_coc_direct_manager,purchase.coc direct manager,model_purchase_coc,group_purchase_coc_direct_manager,1,1,0,0
|
||||
access_purchase_coc_line_user,purchase.coc.line user,model_purchase_coc_line,base.group_user,1,1,1,1
|
||||
|
|
|
|||
|
|
|
@ -24,10 +24,14 @@
|
|||
|
||||
|
||||
|
||||
<!-- <record id="group_coc_manager_direct" model="res.groups">-->
|
||||
<!-- <field name="name">Manager Direct Group</field>-->
|
||||
<!-- <field name="category_id" ref="odex25_purchase_coc.module_category_coc"/>-->
|
||||
<!-- </record>-->
|
||||
<record id="group_coc_manager_direct" model="res.groups">
|
||||
<field name="name">Manager Direct Group</field>
|
||||
<field name="category_id" ref="odex25_purchase_coc.module_category_coc"/>
|
||||
</record>
|
||||
<record id="group_coc_manual_receipt" model="res.groups">
|
||||
<field name="name">Manual Receipt</field>
|
||||
<field name="category_id" ref="odex25_purchase_coc.module_category_coc"/>
|
||||
</record>
|
||||
|
||||
<!--this for direct manager-->
|
||||
<record id="group_purchase_coc_direct_manager" model="res.groups">
|
||||
|
|
@ -69,27 +73,36 @@
|
|||
<field name="groups" eval="[(4, ref('odex25_purchase_coc.group_coc_user'))]"/>
|
||||
</record>
|
||||
|
||||
<record id="purchase_coc_rule_manager" model="ir.rule">
|
||||
<field name="name">Purchase COC Manager</field>
|
||||
<record id="purchase_coc_rule_manager" model="ir.rule">
|
||||
<field name="name">Purchase COC – With Request (CEO or Creator)</field>
|
||||
<field name="model_id" ref="model_purchase_coc"/>
|
||||
<field name="domain_force">['|','|',('create_uid', '=', user.id),('po_id.request_id.employee_id.coach_id.user_id', '=', user.id),('po_id.employee_id.coach_id.user_id', '=', user.id)]
|
||||
<field name="domain_force">
|
||||
['&',
|
||||
('po_id.request_id', '!=', False),
|
||||
'|',
|
||||
('create_uid', '=', user.id),
|
||||
('po_id.request_id.chief_executive_officer', '=', user.id)
|
||||
]
|
||||
</field>
|
||||
<field name="groups" eval="[(4, ref('odex25_purchase_coc.group_coc_manager'))]"/>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
<record id="purchase_coc_rule_manager_no_request" model="ir.rule">
|
||||
<field name="name">Purchase COC Manager (No Request)</field>
|
||||
<field name="model_id" ref="model_purchase_coc"/>
|
||||
<field name="domain_force">
|
||||
[
|
||||
('po_id.request_id', '=', False),
|
||||
('po_id.department_id.manager_id.coach_id.user_id', '=', user.id)
|
||||
]
|
||||
</field>
|
||||
<field name="groups" eval="[(4, ref('odex25_purchase_coc.group_coc_manager'))]"/>
|
||||
</record>
|
||||
<record id="purchase_coc_rule_manager_no_request" model="ir.rule">
|
||||
<field name="name">Purchase COC – No Request (CEO or Creator)</field>
|
||||
<field name="model_id" ref="model_purchase_coc"/>
|
||||
<field name="domain_force">
|
||||
['&',
|
||||
('po_id.request_id', '=', False),
|
||||
'|',
|
||||
('create_uid', '=', user.id),
|
||||
('po_id.chief_executive_officer', '=', user.id)
|
||||
]
|
||||
</field>
|
||||
<field name="groups" eval="[(4, ref('odex25_purchase_coc.group_coc_manager'))]"/>
|
||||
</record>
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
<odoo>
|
||||
<data>
|
||||
<!-- purchase.order inherit form view -->
|
||||
<!-- purchase.order inherit form view -->
|
||||
<record id="view_id" model="ir.ui.view">
|
||||
<field name="name">purchase.order.inherit.view.form</field>
|
||||
<field name="model">purchase.order</field>
|
||||
|
|
@ -17,7 +17,20 @@
|
|||
<!-- <field name="need_coc"/> -->
|
||||
<!-- <field name="coc_id" readonly="1"/> -->
|
||||
<field name="coc_created" invisible="1"/>
|
||||
<field name="is_manual_receipt_user" invisible="1"/>
|
||||
</xpath>
|
||||
<xpath expr="//field[@name='order_line']//field[@name='qty_received']" position="attributes">
|
||||
<attribute name="attrs">
|
||||
{
|
||||
'column_invisible': [('parent.state', 'not in', ('purchase', 'done'))],
|
||||
'readonly': ['|',
|
||||
('qty_received_method', '!=', 'manual'),
|
||||
('parent.is_manual_receipt_user', '=', False)
|
||||
]
|
||||
}
|
||||
</attribute>
|
||||
</xpath>
|
||||
|
||||
</field>
|
||||
</record>
|
||||
|
||||
|
|
@ -53,8 +66,8 @@
|
|||
<field name="state" widget="statusbar"/>
|
||||
</header>
|
||||
|
||||
<sheet>
|
||||
<group>
|
||||
<sheet>
|
||||
|
||||
<div class="oe_button_box" name="button_box">
|
||||
<button name="get_attachments"
|
||||
type="object"
|
||||
|
|
@ -63,60 +76,105 @@
|
|||
<field name="attach_no" widget="statinfo" string="Documents"/>
|
||||
</button>
|
||||
</div>
|
||||
</group>
|
||||
|
||||
<group col="4" colspan="2">
|
||||
<field name="po_id" readonly="1"/>
|
||||
<field name="vendor_id" readonly="1"/>
|
||||
<field name="date" readonly="1"/>
|
||||
<field name="coc_stage"/>
|
||||
<!-- <field name="tender_name"/>-->
|
||||
<field name="receiving_meth"/>
|
||||
|
||||
<field name="parent_coc_id" readonly="1"/>
|
||||
<field name="qty_received_fake_coc" readonly="1" invisible="1"
|
||||
attrs="{'invisible': [('state', '!=', 'approve')]}" />
|
||||
<field name="is_return" readonly="1" invisible="1"/>
|
||||
</group>
|
||||
<group col="2">
|
||||
|
||||
<group>
|
||||
<field name="po_id" readonly="1"/>
|
||||
<field name="date" readonly="1"/>
|
||||
<field name="tender_name"/>
|
||||
<field name="parent_coc_id" readonly="1"/>
|
||||
</group>
|
||||
|
||||
<group>
|
||||
|
||||
<field name="vendor_id" readonly="1"/>
|
||||
<field name="coc_stage" attrs="{'readonly': [('state', '=', 'approve')]}"/>
|
||||
<field name="receiving_meth" attrs="{'readonly': [('state', '=', 'approve')]}"/>
|
||||
|
||||
|
||||
<field name="work_done_scope"
|
||||
widget="radio"
|
||||
options="{'horizontal': true}"
|
||||
attrs="{'readonly': [('state', '=', 'approve')]}"/>
|
||||
<field name="work_done_scope_reason"
|
||||
attrs="{
|
||||
'readonly': [('state', '=', 'approve')],
|
||||
'invisible': [('work_done_scope', '!=', 'no')],
|
||||
'required': [('work_done_scope', '=', 'no')]
|
||||
}"/>
|
||||
|
||||
<field name="work_acceptable"
|
||||
widget="radio"
|
||||
options="{'horizontal': true}"
|
||||
attrs="{'readonly': [('state', '=', 'approve')]}"/>
|
||||
<field name="work_acceptable_reason"
|
||||
attrs="{
|
||||
'readonly': [('state', '=', 'approve')],
|
||||
'invisible': [('work_acceptable', '!=', 'no')],
|
||||
'required': [('work_acceptable', '=', 'no')]
|
||||
}"/>
|
||||
|
||||
<field name="on_time"
|
||||
widget="radio"
|
||||
options="{'horizontal': true}"
|
||||
attrs="{'readonly': [('state', '=', 'approve')]}"/>
|
||||
<field name="delay_days"
|
||||
attrs="{
|
||||
'readonly': [('state', '=', 'approve')],
|
||||
'invisible': [('on_time', '!=', 'no')],
|
||||
'required': [('on_time', '=', 'no')]
|
||||
}"/>
|
||||
<field name="delay_reason"
|
||||
attrs="{
|
||||
'readonly': [('state', '=', 'approve')],
|
||||
'invisible': [('on_time', '!=', 'no')],
|
||||
'required': [('on_time', '=', 'no')]
|
||||
}"/>
|
||||
|
||||
</group>
|
||||
|
||||
</group>
|
||||
|
||||
|
||||
|
||||
<notebook>
|
||||
<page string="Products" name="products">
|
||||
<field name="po_line_ids" readonly="0" attrs="{'invisible': [('is_return', '=', True)]}">
|
||||
<tree editable="bottom">
|
||||
<field name="order_id" readonly="1"/>
|
||||
<field name="name" readonly="1"/>
|
||||
<field name="partner_id" readonly="1"/>
|
||||
<field name="product_id" readonly="1"/>
|
||||
<field name="price_unit" readonly="1"/>
|
||||
<field name="product_qty" readonly="1"/>
|
||||
<field name="show_percentage" invisible="1"/>
|
||||
<field name="qty_percentage" attrs="{'invisible': [('show_percentage', '=', False)]}"/>
|
||||
<field name="qty_received_fake"/>
|
||||
<field name="qty_received" readonly="1" invisible="1"/>
|
||||
<field name="back_qty_remain" readonly="1"/>
|
||||
<field name="product_uom" readonly="1"/>
|
||||
<field name="price_subtotal" readonly="1"/>
|
||||
<field name="date_planned" readonly="1"/>
|
||||
</tree>
|
||||
</field >
|
||||
<field name="po_return_line_ids" readonly="0" attrs="{'invisible': [('is_return', '=', False)]}">
|
||||
<tree editable="bottom">
|
||||
<field name="order_id" readonly="1"/>
|
||||
<field name="name" readonly="1"/>
|
||||
<field name="partner_id" readonly="1"/>
|
||||
<field name="product_id" readonly="1"/>
|
||||
<field name="price_unit" readonly="1"/>
|
||||
<field name="show_percentage" invisible="1"/>
|
||||
<field name="qty_percentage" attrs="{'invisible': [('show_percentage', '=', False)]}"/>
|
||||
<page string="Products" name="products">
|
||||
<field name="coc_line_ids" attrs="{'readonly': [('state', '=', 'approve')]}">
|
||||
<tree editable="bottom" create="false" delete="false"
|
||||
decoration-success="qty_to_receive > 0"
|
||||
decoration-muted="qty_remaining == 0">
|
||||
<field name="product_id" readonly="1" width="20"/>
|
||||
<field name="name" readonly="1" width="20"/>
|
||||
<field name="qty_ordered" readonly="1" width="20" string="Total Ordered"/>
|
||||
<field name="product_uom" width="20" readonly="1"/>
|
||||
<field name="qty_received_total" readonly="1" width="20" string="Previously Received"/>
|
||||
<!-- <field name="product_qty" readonly="1" width="20" string="Current Order Qty"/>-->
|
||||
<field name="qty_remaining" readonly="1" width="20" string="Remaining"/>
|
||||
|
||||
<field name="qty_received_fake"/>
|
||||
<field name="qty_received" readonly="1" invisible="1"/>
|
||||
<field name="back_qty_remain" readonly="1"/>
|
||||
<field name="product_uom" readonly="1"/>
|
||||
<field name="price_subtotal" readonly="1"/>
|
||||
<field name="date_planned" readonly="1"/>
|
||||
</tree>
|
||||
</field >
|
||||
</page>
|
||||
<field name="show_percentage" invisible="1"/>
|
||||
<field name="qty_percentage" width="40"
|
||||
attrs="{'column_invisible': [('parent.receiving_meth', '!=', 'percentage')],
|
||||
'readonly': [('qty_remaining', '=', 0)]}"
|
||||
string="%"/>
|
||||
|
||||
<field name="qty_to_receive" width="20"
|
||||
string="Qty to Receive"
|
||||
attrs="{'column_invisible': [('parent.receiving_meth', '=', 'percentage')],
|
||||
'readonly': [('qty_remaining', '=', 0)]}"
|
||||
/>
|
||||
|
||||
<field name="date_planned" width="20" attrs="{'readonly': [('parent.state', '=', 'approve')]}" />
|
||||
<field name="price_unit" width="20" readonly="1"/>
|
||||
<field name="sub_price_total" width="20" readonly="1"/>
|
||||
|
||||
|
||||
<field name="po_line_id" invisible="1"/>
|
||||
<field name="receiving_meth" invisible="1"/>
|
||||
</tree>
|
||||
</field>
|
||||
</page>
|
||||
<page string="Note" name="note">
|
||||
<field name="note"/>
|
||||
</page>
|
||||
|
|
|
|||
|
|
@ -2,26 +2,30 @@ from odoo import models, fields, api, _
|
|||
from datetime import datetime
|
||||
from odoo.exceptions import ValidationError
|
||||
|
||||
import json
|
||||
|
||||
class PurchaseCocPartialWizard(models.TransientModel):
|
||||
import ast
|
||||
class PurchaseCoCPartialWizard(models.TransientModel):
|
||||
_name = 'purchase.coc.partial.wizard'
|
||||
_description = 'Partial Quantities Wizard for CoC'
|
||||
confirm_create = fields.Boolean(string="Do you want to create a new CoC?", default=True)
|
||||
coc_id = fields.Many2one('purchase.coc', string="CoC")
|
||||
backorder_line_ids = fields.Many2many('purchase.order.line', string="Backorder Lines")
|
||||
|
||||
|
||||
|
||||
_description = 'CoC Partial Receipt Wizard'
|
||||
|
||||
coc_id = fields.Many2one('purchase.coc', string='CoC', required=True)
|
||||
backorder_lines_data = fields.Text(string='Backorder Lines Data')
|
||||
create_backorder = fields.Boolean(string='Create Backorder?', default=True)
|
||||
|
||||
def action_confirm(self):
|
||||
print("action_confirm")
|
||||
self.ensure_one()
|
||||
coc = self.coc_id
|
||||
|
||||
backorder = coc._create_backorder(self.backorder_line_ids.ids)
|
||||
coc.write({'return_id': backorder.id})
|
||||
|
||||
return coc._get_backorder_action(backorder)
|
||||
if self.create_backorder and self.backorder_lines_data:
|
||||
lines_data = ast.literal_eval(self.backorder_lines_data)
|
||||
|
||||
|
||||
backorder = self.coc_id._create_backorder_coc(lines_data)
|
||||
self.coc_id.write({'state': 'approve'})
|
||||
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
def action_cancel(self):
|
||||
self.ensure_one()
|
||||
self.coc_id.write({'state': 'approve'})
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
|
@ -11,7 +11,7 @@ You have processed less product than the initial order.
|
|||
|
||||
<footer>
|
||||
<button name="action_confirm" string="Create Backorder" type="object" class="btn-primary"/>
|
||||
<button string="No Backorder" class="btn-secondary" special="cancel"/>
|
||||
<button name="action_cancel" string="No Backorder" type="object" class="btn-secondary"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
|
|
|
|||
Loading…
Reference in New Issue