Added Employee Custody to Purchase Request
This commit is contained in:
parent
4b9313d21c
commit
f0516f36e7
|
|
@ -16,7 +16,8 @@
|
|||
'views/report_deliveryslip.xml',
|
||||
'views/product_template.xml',
|
||||
'views/account_asset_operation.xml',
|
||||
'wizards/picking_purchase_request.xml'
|
||||
'wizards/picking_purchase_request.xml',
|
||||
'wizards/asset_operation_return_wizard.xml',
|
||||
|
||||
],
|
||||
'depends': ['stock', 'purchase_requisition', 'purchase_requisition_custom','exp_asset_custody_link'],
|
||||
|
|
|
|||
|
|
@ -20,6 +20,27 @@ msgstr ""
|
|||
msgid "Approve Warehouse"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__asset_id
|
||||
msgid "Asset"
|
||||
msgstr "الأصل"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_purchase_request__all_assets_released
|
||||
msgid "All Assets Released"
|
||||
msgstr "تم إرجاع جميع الأصول"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: code:addons/purchase_custom_stock/models/purchase_request.py:0
|
||||
#, python-format
|
||||
msgid "Asset Availability Warning"
|
||||
msgstr "تحذير توفر الأصل"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_purchase_request__asset_custody_complete
|
||||
msgid "Asset Custody Complete"
|
||||
msgstr "اكتملت عهدة الأصل"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_purchase_request__asset_assign_count
|
||||
msgid "Asset Assignment"
|
||||
|
|
@ -41,6 +62,16 @@ msgstr "بند الأصول"
|
|||
msgid "Asset Operation"
|
||||
msgstr "عمليات الأصول"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model,name:purchase_custom_stock.model_asset_operation_return_line
|
||||
msgid "Asset Operation Return Line"
|
||||
msgstr "سطر عملية إرجاع الأصل"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model,name:purchase_custom_stock.model_asset_operation_return_wizard
|
||||
msgid "Asset Operation Return Wizard"
|
||||
msgstr "عمليةإرجاع الأصل"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_purchase_request__asset_release_count
|
||||
msgid "Asset Release"
|
||||
|
|
@ -61,6 +92,11 @@ msgstr "إسناد عهدة"
|
|||
msgid "Assets Release"
|
||||
msgstr "إرجاع عهدة"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__type__assignment
|
||||
msgid "Assignment"
|
||||
msgstr "أسناد"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_custom_stock.purchase_request_form_inherit
|
||||
msgid "Assignments"
|
||||
|
|
@ -89,7 +125,9 @@ msgid "Can't Confirm Request With No Item!"
|
|||
msgstr ""
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__state__cancel
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__purchase_request__state__cancel
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_custom_stock.asset_operation_return_wizard_view_form
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_custom_stock.purchase_request_picking_wizard_view_form
|
||||
msgid "Cancel"
|
||||
msgstr "إلغاء"
|
||||
|
|
@ -120,11 +158,31 @@ msgstr "تحويل الى المشتريات"
|
|||
msgid "Created by"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_custom_stock.purchase_request_form_inherit
|
||||
msgid "Create Asset Custody"
|
||||
msgstr "إنشاء و اسناد الأصل"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_purchase_request_picking_wizard__create_date
|
||||
msgid "Created on"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__date
|
||||
msgid "Date"
|
||||
msgstr "التاريخ"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__custody_type
|
||||
msgid "Custody Type"
|
||||
msgstr "نوع العهدة"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__custody_period
|
||||
msgid "Custody Period"
|
||||
msgstr "فترة العهدة"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_custom_stock.purchase_request_form_inherit
|
||||
msgid "Delivery"
|
||||
|
|
@ -145,22 +203,32 @@ msgstr "تسليم المتوفر وشراء الباقى"
|
|||
msgid "Demand Qty"
|
||||
msgstr "الكمية المطلوبة"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__current_department_id
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__new_department_id
|
||||
msgid "Department"
|
||||
msgstr "القسم"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__purchase_request__state__direct_manager
|
||||
msgid "Direct Manager"
|
||||
msgstr "المدير المباشر"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__display_name
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_wizard__display_name
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_purchase_request_picking_wizard__display_name
|
||||
msgid "Display Name"
|
||||
msgstr ""
|
||||
msgstr "الاسم المعروض"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__state__done
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__purchase_request__state__done
|
||||
msgid "Done"
|
||||
msgstr "تم"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__state__draft
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__purchase_request__state__draft
|
||||
msgid "Draft"
|
||||
msgstr "مبدئي"
|
||||
|
|
@ -170,6 +238,17 @@ msgstr "مبدئي"
|
|||
msgid "Edit Locations"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__current_employee_id
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__new_employee_id
|
||||
msgid "Employee"
|
||||
msgstr "الموظف"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__custody_type__general
|
||||
msgid "General"
|
||||
msgstr "عام"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__purchase_request__state__employee
|
||||
msgid "Employee Delivery"
|
||||
|
|
@ -216,11 +295,37 @@ msgstr ""
|
|||
msgid "Location"
|
||||
msgstr "الموقع/المكان"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: code:addons/purchase_custom_stock/models/purchase_request.py:0
|
||||
#, python-format
|
||||
msgid "No available assets found for the following products: {}"
|
||||
msgstr "لا توجد أصول متاحة للمنتجات التالية: {}"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__name
|
||||
msgid "Name"
|
||||
msgstr "الاسم"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:stock.picking.type,name:purchase_custom_stock.stock_picking_type_stock
|
||||
msgid "Out From Stock"
|
||||
msgstr "صرف من المخزون"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__state__pending
|
||||
msgid "Pending"
|
||||
msgstr "قيد الانتظار"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__custody_type__personal
|
||||
msgid "Personal"
|
||||
msgstr "شخصية"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__custody_period__permanent
|
||||
msgid "Permanent"
|
||||
msgstr "دائمة"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_purchase_request__picking_id
|
||||
msgid "Picking"
|
||||
|
|
@ -262,6 +367,12 @@ msgstr ""
|
|||
msgid "Please Select department for employee"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: code:addons/purchase_custom_stock/wizards/asset_operation_return_wizard.py:0
|
||||
#, python-format
|
||||
msgid "Please select at least one asset to return"
|
||||
msgstr "يرجى اختيار أصل واحد على الأقل لإرجاعه"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_purchase_request_line__qty_purchased
|
||||
msgid "Purchase Qty"
|
||||
|
|
@ -269,8 +380,16 @@ msgstr "الكمية المطلوبة للشراء"
|
|||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model,name:purchase_custom_stock.model_purchase_request
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_custody_line__purchase_request_id
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__purchase_request_id
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_wizard__purchase_request_id
|
||||
msgid "Purchase Request"
|
||||
msgstr "طلبات الادارات"
|
||||
msgstr "طلبات الإدارات"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__type__release
|
||||
msgid "Release"
|
||||
msgstr "إرجاع"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__purchase_request__state__refuse
|
||||
|
|
@ -297,6 +416,34 @@ msgstr ""
|
|||
msgid "Show Purchase Only"
|
||||
msgstr ""
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__custody_period__temporary
|
||||
msgid "Temporary"
|
||||
msgstr "مؤقتة"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model,name:purchase_custom_stock.model_stock_picking
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__type__transfer
|
||||
msgid "Transfer"
|
||||
msgstr "نقل"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__type
|
||||
msgid "Type"
|
||||
msgstr "النوع"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,help:purchase_custom_stock.field_purchase_request__asset_custody_complete
|
||||
msgid ""
|
||||
"True when all asset products have custody lines and operations in done state"
|
||||
msgstr ""
|
||||
"صحيح عندما تحتوي جميع منتجات الأصول على خطوط الحيازة والعمليات في حالة منتهية"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields.selection,name:purchase_custom_stock.selection__asset_operation_return_line__state__submit
|
||||
msgid "Submit"
|
||||
msgstr "إرسال"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_purchase_request__state
|
||||
msgid "State"
|
||||
|
|
@ -329,6 +476,18 @@ msgstr "مدير المستودع"
|
|||
msgid "Warehouses Department"
|
||||
msgstr "ادارة المستودعات"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__wizard_id
|
||||
msgid "Wizard"
|
||||
msgstr "المعالج"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: code:addons/purchase_custom_stock/models/refuse_reason.py:0
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You have assigned an asset. Please return it before refusing the request."
|
||||
msgstr "لقد قمت بتعيين أصل. يرجى إرجاعه قبل رفض الطلب"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: code:addons/purchase_custom_stock/models/purchase_request.py:0
|
||||
#, python-format
|
||||
|
|
@ -345,6 +504,23 @@ msgstr ""
|
|||
msgid "purchase request line"
|
||||
msgstr "بند طلب الشراء"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: code:addons/purchase_custom_stock/models/purchase_request.py:0
|
||||
#: model:ir.actions.act_window,name:purchase_custom_stock.action_asset_operation_return_wizard
|
||||
#: model_terms:ir.ui.view,arch_db:purchase_custom_stock.asset_operation_return_wizard_view_form
|
||||
#, python-format
|
||||
msgid "Return Assets"
|
||||
msgstr "إرجاع الأصول"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_wizard__operation_ids
|
||||
msgid "Return Operations"
|
||||
msgstr "عمليات الإرجاع"
|
||||
|
||||
#. module: purchase_custom_stock
|
||||
#: model:ir.model.fields,field_description:purchase_custom_stock.field_asset_operation_return_line__user_id
|
||||
msgid "Responsible"
|
||||
msgstr "المسؤول"
|
||||
|
||||
#. module: stock
|
||||
#: model:ir.ui.menu,name:stock.menu_stock_root
|
||||
|
|
|
|||
|
|
@ -4,4 +4,12 @@ from . import stock_warehouse
|
|||
from . import stock_picking
|
||||
from . import product_template
|
||||
from . import employee_custody
|
||||
from . import account_asset_operation
|
||||
from . import account_asset_operation
|
||||
from . import refuse_reason
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -10,4 +10,20 @@ class EmployeeCustodyLine(models.Model):
|
|||
|
||||
purchase_request_id = fields.Many2one(comodel_name='purchase.request', string="Purchase Request")
|
||||
|
||||
@api.onchange('asset_id')
|
||||
def _onchange_asset_id(self):
|
||||
if not self.purchase_request_id:
|
||||
return
|
||||
|
||||
selected_asset_ids = self.purchase_request_id.asset_request_line_ids.filtered(
|
||||
lambda l: l != self
|
||||
).mapped('asset_id.id')
|
||||
|
||||
domain = [
|
||||
('id', 'not in', selected_asset_ids),
|
||||
('status', 'in', ['new', 'available']),
|
||||
('asset_type', '=', 'purchase'),
|
||||
('product_id', 'in', self.purchase_request_id.line_ids.mapped('product_id.id'))
|
||||
]
|
||||
|
||||
return {'domain': {'asset_id': domain}}
|
||||
|
|
@ -31,6 +31,11 @@ class PurchaseRequest(models.Model):
|
|||
asset_request_line_ids = fields.One2many('asset.custody.line', 'purchase_request_id')
|
||||
asset_assign_count = fields.Integer(compute='_asset_assign_count', string='Asset Assignment')
|
||||
asset_release_count = fields.Integer(compute='_asset_release_count', string='Asset Release')
|
||||
all_assets_released = fields.Boolean(string="All Assets Released", compute="_compute_all_assets_released")
|
||||
asset_custody_complete = fields.Boolean(compute='_compute_asset_custody_complete',
|
||||
string='Asset Custody Complete',
|
||||
help='True when all asset products have custody lines and operations in done state'
|
||||
)
|
||||
|
||||
def _asset_assign_count(self):
|
||||
self.asset_assign_count = len(
|
||||
|
|
@ -59,6 +64,57 @@ class PurchaseRequest(models.Model):
|
|||
else:
|
||||
rec.show_asset_release_button = False
|
||||
|
||||
@api.depends('asset_request_line_ids')
|
||||
def _compute_all_assets_released(self):
|
||||
for rec in self:
|
||||
rec.all_assets_released = False
|
||||
if not rec.asset_request_line_ids:
|
||||
continue
|
||||
asset_ids = rec.asset_request_line_ids.mapped('asset_id.id')
|
||||
if not asset_ids:
|
||||
continue
|
||||
release_ops = self.env['account.asset.operation'].search([
|
||||
('purchase_request_id', '=', rec.id),
|
||||
('asset_id', 'in', asset_ids),
|
||||
('type', '=', 'release'),
|
||||
('state', '=', 'done')
|
||||
])
|
||||
released_asset_ids = release_ops.mapped('asset_id.id')
|
||||
rec.all_assets_released = all(asset_id in released_asset_ids for asset_id in asset_ids)
|
||||
|
||||
@api.depends('line_ids', 'asset_request_line_ids')
|
||||
def _compute_asset_custody_complete(self):
|
||||
for record in self:
|
||||
asset_custody_complete = True
|
||||
asset_products = record.line_ids.filtered(lambda l: l.product_id.asset_ok)
|
||||
if not asset_products:
|
||||
record.asset_custody_complete = False
|
||||
continue
|
||||
for line in asset_products:
|
||||
required_qty = int(line.qty)
|
||||
existing_custody_count = self.env['asset.custody.line'].search_count([
|
||||
('purchase_request_id', '=', record.id),
|
||||
('asset_id.product_id', '=', line.product_id.id)
|
||||
])
|
||||
|
||||
if existing_custody_count != required_qty:
|
||||
asset_custody_complete = False
|
||||
break
|
||||
if asset_custody_complete and record.asset_request_line_ids:
|
||||
for custody_line in record.asset_request_line_ids:
|
||||
done_ops_count = self.env['account.asset.operation'].search_count([
|
||||
('purchase_request_id', '=', record.id),
|
||||
('type', '=', 'assignment'),
|
||||
('asset_id', '=', custody_line.asset_id.id),
|
||||
('state', '=', 'done')
|
||||
])
|
||||
|
||||
if done_ops_count == 0:
|
||||
asset_custody_complete = False
|
||||
break
|
||||
|
||||
record.asset_custody_complete = asset_custody_complete
|
||||
|
||||
def show_employee_button(self):
|
||||
"""show only for the create employee"""
|
||||
for rec in self:
|
||||
|
|
@ -199,10 +255,7 @@ class PurchaseRequest(models.Model):
|
|||
asset_product_lines.filtered(lambda asset_line: asset_line.qty > asset_line.available_qty)) or any(
|
||||
consu_product_not_asset_lines.filtered(lambda asset_line: asset_line.qty > asset_line.available_qty)):
|
||||
if self.has_asset_product_line:
|
||||
if not self.asset_request_line_ids and any(
|
||||
asset_product_lines.filtered(lambda line: line.available_qty > 0)):
|
||||
raise Warning(_('Please Select an asset'))
|
||||
self.create_asset_operation()
|
||||
self.create_asset_custody_lines()
|
||||
context = {}
|
||||
view = self.env.ref('purchase_custom_stock.purchase_request_picking_wizard_view_form')
|
||||
wiz = self.env['purchase.request_picking.wizard']
|
||||
|
|
@ -246,9 +299,7 @@ class PurchaseRequest(models.Model):
|
|||
picking_id = self.env['stock.picking'].create(picking_vals)
|
||||
self.picking_id = picking_id.id
|
||||
if self.has_asset_product_line:
|
||||
if not self.asset_request_line_ids:
|
||||
raise Warning(_('Please Select an asset'))
|
||||
self.create_asset_operation()
|
||||
self.create_asset_custody_lines()
|
||||
if non_storable_product:
|
||||
for rec in non_storable_product:
|
||||
rec.qty_purchased = rec.qty
|
||||
|
|
@ -278,7 +329,7 @@ class PurchaseRequest(models.Model):
|
|||
if line.product_id.asset_ok:
|
||||
asset_count = self.env['account.asset'].search_count([
|
||||
('product_id', '=', line.product_id.id),
|
||||
('status', 'in', ['new', 'available'])
|
||||
('status', 'in', ['new', 'available']), ('asset_type', '=', 'purchase')
|
||||
])
|
||||
line.available_qty = asset_count
|
||||
line.qty_purchased = line.qty - asset_count
|
||||
|
|
@ -358,7 +409,16 @@ class PurchaseRequest(models.Model):
|
|||
return res
|
||||
|
||||
def create_asset_operation(self):
|
||||
AssetOperation = self.env['account.asset.operation']
|
||||
for asset in self.asset_request_line_ids:
|
||||
exists = AssetOperation.search_count([
|
||||
('purchase_request_id', '=', self.id),
|
||||
('type', '=', 'assignment'),
|
||||
('asset_id', '=', asset.asset_id.id),
|
||||
('state', '!=', 'cancel')
|
||||
])
|
||||
if exists:
|
||||
continue
|
||||
data = {
|
||||
'date': self.date,
|
||||
'asset_id': asset.asset_id.id,
|
||||
|
|
@ -372,7 +432,66 @@ class PurchaseRequest(models.Model):
|
|||
'purchase_request_id': self.id,
|
||||
|
||||
}
|
||||
self.env['account.asset.operation'].create(data)
|
||||
AssetOperation.create(data)
|
||||
|
||||
def create_asset_custody_lines(self):
|
||||
Asset = self.env['account.asset']
|
||||
CustodyLine = self.env['asset.custody.line']
|
||||
custody_lines = []
|
||||
products_with_issues = []
|
||||
|
||||
existing_asset_ids = self.asset_request_line_ids.mapped('asset_id.id')
|
||||
|
||||
for line in self.line_ids.filtered(lambda l: l.product_id.asset_ok):
|
||||
required_qty = int(line.qty)
|
||||
|
||||
already_assigned = CustodyLine.search_count([
|
||||
('purchase_request_id', '=', self.id),
|
||||
('asset_id.product_id', '=', line.product_id.id)
|
||||
])
|
||||
remaining_qty = required_qty - already_assigned
|
||||
if remaining_qty <= 0:
|
||||
continue
|
||||
available_assets = Asset.search([
|
||||
('product_id', '=', line.product_id.id),
|
||||
('status', 'in', ['new', 'available']),
|
||||
('asset_type', '=', 'purchase'),
|
||||
('id', 'not in', existing_asset_ids)
|
||||
], limit=remaining_qty)
|
||||
|
||||
if not available_assets:
|
||||
products_with_issues.append(line.product_id.name)
|
||||
continue
|
||||
|
||||
for asset in available_assets:
|
||||
# asset.status = 'reserved'
|
||||
custody_lines.append({
|
||||
'purchase_request_id': self.id,
|
||||
'asset_id': asset.id,
|
||||
'type': 'assignment',
|
||||
'custody_type': 'personal',
|
||||
'custody_period': 'temporary',
|
||||
'date': self.date or fields.Date.today(),
|
||||
})
|
||||
|
||||
if custody_lines:
|
||||
CustodyLine.create(custody_lines)
|
||||
if products_with_issues:
|
||||
warning_message = _("No available assets found for the following products: {}").format(
|
||||
", ".join(products_with_issues)
|
||||
)
|
||||
return {
|
||||
'type': 'ir.actions.client',
|
||||
'tag': 'display_notification',
|
||||
'params': {
|
||||
'title': _('Asset Availability Warning'),
|
||||
'message': warning_message,
|
||||
'sticky': True,
|
||||
'type': 'warning',
|
||||
}
|
||||
}
|
||||
self.create_asset_operation()
|
||||
return True
|
||||
|
||||
def asset_operation_release(self):
|
||||
for asset in self.asset_request_line_ids:
|
||||
|
|
@ -393,9 +512,54 @@ class PurchaseRequest(models.Model):
|
|||
}
|
||||
self.env['account.asset.operation'].create(data)
|
||||
|
||||
def return_asset(self):
|
||||
self.asset_operation_release()
|
||||
def return_account_asset_operation(self):
|
||||
self.ensure_one()
|
||||
context = {}
|
||||
view = self.env.ref('purchase_custom_stock.asset_operation_return_wizard_view_form')
|
||||
assigned_operations = self.env['account.asset.operation'].search([
|
||||
('purchase_request_id', '=', self.id),
|
||||
('type', '=', 'assignment'),
|
||||
('state', '=', 'done')
|
||||
])
|
||||
released_asset_ids = self.env['account.asset.operation'].search([
|
||||
('purchase_request_id', '=', self.id),
|
||||
('type', '=', 'release'),
|
||||
('state', '!=', 'cancel')
|
||||
]).mapped('asset_id.id')
|
||||
available_operations = assigned_operations.filtered(
|
||||
lambda op: op.asset_id.id not in released_asset_ids
|
||||
)
|
||||
|
||||
operation_vals = []
|
||||
for op in available_operations:
|
||||
operation_vals.append((0, 0, {
|
||||
'name': op.asset_id.name,
|
||||
'date': self.date,
|
||||
'asset_id': op.asset_id.id,
|
||||
'type': 'release',
|
||||
'custody_type': op.custody_type,
|
||||
'custody_period': op.custody_period,
|
||||
'state': 'draft',
|
||||
'user_id': self.env.uid,
|
||||
'current_employee_id': self.employee_id.id,
|
||||
'new_employee_id': self.employee_id.id,
|
||||
'current_department_id': self.department_id.id,
|
||||
'purchase_request_id': self.id,
|
||||
}))
|
||||
context['default_purchase_request_id'] = self.id
|
||||
context['default_operation_ids'] = operation_vals
|
||||
|
||||
return {
|
||||
'name': _('Return Assets'),
|
||||
'type': 'ir.actions.act_window',
|
||||
'view_type': 'form',
|
||||
'view_mode': 'form',
|
||||
'res_model': 'asset.operation.return.wizard',
|
||||
'views': [(view.id, 'form')],
|
||||
'view_id': view.id,
|
||||
'target': 'new',
|
||||
'context': context,
|
||||
}
|
||||
|
||||
class PurchaseRequestLine(models.Model):
|
||||
_inherit = 'purchase.request.line'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
from odoo import api, fields, models, _
|
||||
|
||||
|
||||
class RefuseReason(models.TransientModel):
|
||||
_inherit = "refuse.reason"
|
||||
|
||||
def action_refuse(self):
|
||||
res = super(RefuseReason, self).action_refuse()
|
||||
if self.request_id:
|
||||
request_id = self.env['purchase.request'].search([('id', '=', self.request_id)])
|
||||
if any(request_id.asset_request_line_ids.filtered(lambda line: line.asset_id.status == 'assigned')):
|
||||
raise ValidationError(
|
||||
_("You have assigned an asset. Please return it before refusing the request."))
|
||||
else:
|
||||
# for line in request_id.asset_request_line_ids:
|
||||
# if line.asset_id:
|
||||
# line.asset_id.status = 'available'
|
||||
request_id.asset_request_line_ids.unlink()
|
||||
return res
|
||||
|
|
@ -1,3 +1,5 @@
|
|||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
|
||||
model_convert_picking_wizard_user,picking_wizard,model_purchase_request_picking_wizard,base.group_user,1,1,1,1
|
||||
asset_operation_return_wizard,asset_operation_return_wizard,model_asset_operation_return_wizard,base.group_user,1,1,1,1
|
||||
asset_operation_return_line,asset_operation_return_line,model_asset_operation_return_line,base.group_user,1,1,1,1
|
||||
|
|
|
|||
|
|
|
@ -42,7 +42,7 @@
|
|||
<button class="oe_stat_button" type="action"
|
||||
groups="exp_asset_base.group_assets_manager,stock.group_stock_manager"
|
||||
name="%(action_account_asset_release)d" icon="fa-pencil"
|
||||
attrs="{'invisible':['|','|',('asset_release_count','=',0),('show_asset_release_button','=',False),('state', 'not in', ('done','employee'))]}">
|
||||
attrs="{'invisible':['|','|',('asset_release_count','=',0),('show_asset_release_button','=',False),('state', 'not in', ('done','employee','wait_for_send'))]}">
|
||||
<field name="asset_release_count" string="Releases" widget="statinfo"/>
|
||||
</button>
|
||||
</xpath>
|
||||
|
|
@ -62,6 +62,8 @@
|
|||
<field name="show_approve_warehouse" invisible="0"/>
|
||||
<field name="has_asset_product_line" invisible="1"/>
|
||||
<field name="show_asset_release_button" invisible="1"/>
|
||||
<field name="all_assets_released" invisible="1"/>
|
||||
<field name="asset_custody_complete" invisible="1"/>
|
||||
<div>
|
||||
<label for="warehouse_id"/>
|
||||
<field name="warehouse_id"
|
||||
|
|
@ -95,9 +97,17 @@
|
|||
type="object" string="Available Quantity"
|
||||
attrs="{'invisible':[('show_approve_warehouse' , '=' , False)]}" class="oe_highlight"
|
||||
groups="stock.group_stock_user,stock.group_stock_manager"/>
|
||||
<button name="return_asset"
|
||||
</xpath>
|
||||
<xpath expr="//button[@name='action_draft']" position="before">
|
||||
<button name="create_asset_custody_lines"
|
||||
type="object"
|
||||
string="Create Asset Custody"
|
||||
class="oe_highlight"
|
||||
groups="exp_asset_base.group_assets_manager"
|
||||
attrs="{'invisible': ['|','|',('state' , 'not in' , ('done','employee','waiting','wait_for_send','initial')),('has_asset_product_line', '=', False),('asset_custody_complete', '=', True)]}"/>
|
||||
<button name="return_account_asset_operation"
|
||||
type="object" string="Return Done"
|
||||
attrs="{'invisible':['|','|',('state', 'not in', ('done','employee')),('asset_release_count','=',0),('show_asset_release_button','=',False)]}"
|
||||
attrs="{'invisible':['|','|','|',('state', 'not in', ('done','employee','wait_for_send')),('asset_release_count','=',0),('show_asset_release_button','=',False),('all_assets_released','=',True)]}"
|
||||
class="oe_highlight"
|
||||
groups="exp_asset_base.group_assets_manager"/>
|
||||
</xpath>
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
from . import picking_purchase_request
|
||||
from . import asset_operation_return_wizard
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo import api, fields, models, _
|
||||
from odoo.exceptions import UserError, ValidationError
|
||||
|
||||
|
||||
class AssetOperationReturnWizard(models.TransientModel):
|
||||
_name = 'asset.operation.return.wizard'
|
||||
_description = 'Asset Operation Return Wizard'
|
||||
|
||||
purchase_request_id = fields.Many2one('purchase.request', string='Purchase Request', required=True)
|
||||
operation_ids = fields.One2many('asset.operation.return.line', 'wizard_id', string='Return Operations')
|
||||
|
||||
def action_confirm(self):
|
||||
if not self.operation_ids:
|
||||
raise ValidationError(_("Please select at least one asset to return"))
|
||||
|
||||
purchase_request = self.purchase_request_id
|
||||
operation_vals = []
|
||||
|
||||
for line in self.operation_ids:
|
||||
operation_vals.append({
|
||||
'name': line.asset_id.name,
|
||||
'date': purchase_request.date or fields.Date.today(),
|
||||
'asset_id': line.asset_id.id,
|
||||
'type': 'release',
|
||||
'custody_type': line.custody_type,
|
||||
'custody_period': line.custody_period,
|
||||
'state': 'draft',
|
||||
'user_id': line.user_id.id,
|
||||
'current_employee_id': purchase_request.employee_id.id,
|
||||
'new_employee_id': purchase_request.employee_id.id,
|
||||
'current_department_id': purchase_request.department_id.id,
|
||||
'purchase_request_id': purchase_request.id,
|
||||
})
|
||||
self.env['account.asset.operation'].create(operation_vals)
|
||||
|
||||
return {'type': 'ir.actions.act_window_close'}
|
||||
|
||||
|
||||
class AssetOperationReturnLine(models.TransientModel):
|
||||
_name = 'asset.operation.return.line'
|
||||
_description = 'Asset Operation Return Line'
|
||||
|
||||
wizard_id = fields.Many2one('asset.operation.return.wizard', ondelete='cascade')
|
||||
asset_id = fields.Many2one('account.asset', string='Asset', required=True)
|
||||
name = fields.Char(default='/')
|
||||
date = fields.Date()
|
||||
type = fields.Selection(selection=[('assignment', 'Assignment'), ('release', 'Release'),
|
||||
('transfer', 'Transfer')])
|
||||
custody_type = fields.Selection([('personal', 'Personal'), ('general', 'General')], string='Custody Type')
|
||||
custody_period = fields.Selection([('temporary', 'Temporary'), ('permanent', 'Permanent')], string='Custody Period')
|
||||
state = fields.Selection(
|
||||
[('draft', 'Draft'), ('submit', 'Submit'), ('done', 'Done'), ('pending', 'Pending'), ('cancel', 'Cancel')],
|
||||
default='draft')
|
||||
user_id = fields.Many2one('res.users', string='Responsible')
|
||||
current_employee_id = fields.Many2one('hr.employee', string='Employee')
|
||||
new_employee_id = fields.Many2one('hr.employee', string='Employee')
|
||||
current_department_id = fields.Many2one('hr.department', string='Department')
|
||||
new_department_id = fields.Many2one('hr.department', string='Department')
|
||||
purchase_request_id = fields.Many2one('purchase.request')
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<record id="asset_operation_return_wizard_view_form" model="ir.ui.view">
|
||||
<field name="name">asset.operation.return.wizard.form</field>
|
||||
<field name="model">asset.operation.return.wizard</field>
|
||||
<field name="arch" type="xml">
|
||||
<form string="Return Assets">
|
||||
<sheet>
|
||||
<group>
|
||||
<field name="purchase_request_id" readonly="1"/>
|
||||
</group>
|
||||
<field name="operation_ids" create="0" edit="0">
|
||||
<tree create="0" edit="0">
|
||||
<field name="name"/>
|
||||
<field name="asset_id"/>
|
||||
<field name="user_id"/>
|
||||
<field name="date"/>
|
||||
<field name="type"/>
|
||||
<field name="custody_type"/>
|
||||
<field name="custody_period"/>
|
||||
<field name="current_employee_id"/>
|
||||
<field name="current_department_id"/>
|
||||
<field name="state"/>
|
||||
<field name="purchase_request_id" invisible="1"/>
|
||||
</tree>
|
||||
<form create="0" edit="0">
|
||||
<sheet>
|
||||
<group>
|
||||
<group>
|
||||
<field name="name" readonly="1" force_save="1"/>
|
||||
<field name="asset_id" readonly="1" force_save="1"/>
|
||||
<field name="user_id" readonly="1" force_save="1"/>
|
||||
<field name="date" readonly="1" force_save="1"/>
|
||||
<field name="type" readonly="1" force_save="1"/>
|
||||
</group>
|
||||
<group>
|
||||
<field name="custody_type" readonly="1" force_save="1"/>
|
||||
<field name="custody_period" readonly="1" force_save="1"/>
|
||||
<field name="current_employee_id" readonly="1" force_save="1"/>
|
||||
<field name="current_department_id" readonly="1" force_save="1"/>
|
||||
<field name="state" readonly="1" force_save="1"/>
|
||||
</group>
|
||||
</group>
|
||||
<field name="purchase_request_id" invisible="1" force_save="1"/>
|
||||
</sheet>
|
||||
<footer>
|
||||
<button special="cancel" string="Cancel" class="btn-secondary"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</sheet>
|
||||
<footer>
|
||||
<button name="action_confirm" string="Return Assets" type="object" class="btn-primary"/>
|
||||
<button string="Cancel" class="btn-secondary" special="cancel"/>
|
||||
</footer>
|
||||
</form>
|
||||
</field>
|
||||
</record>
|
||||
|
||||
<record id="action_asset_operation_return_wizard" model="ir.actions.act_window">
|
||||
<field name="name">Return Assets</field>
|
||||
<field name="res_model">asset.operation.return.wizard</field>
|
||||
<field name="view_id" ref="asset_operation_return_wizard_view_form"/>
|
||||
<field name="view_mode">form</field>
|
||||
<field name="target">new</field>
|
||||
</record>
|
||||
</odoo>
|
||||
Loading…
Reference in New Issue