Skip to content

Commit b08a2a9

Browse files
Update project with latest changes
1 parent bee448b commit b08a2a9

File tree

15 files changed

+560
-0
lines changed

15 files changed

+560
-0
lines changed

records_management-1/README.md

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
# Records Management Odoo Module
2+
3+
## Overview
4+
The Records Management module for Odoo is designed to streamline the management of records related to shredding services and inventory control. This module allows users to create and manage pickup requests, track shredding services, and maintain an organized inventory of stock items.
5+
6+
## Features
7+
- **Pickup Requests**: Users can create and manage pickup requests for items associated with customers.
8+
- **Shredding Services**: Track shredding services provided to customers, including service types and associated charges.
9+
- **Inventory Management**: View and manage inventory items linked to customers, including serial numbers and quantities.
10+
- **Audit Logging**: Maintain a log of actions taken on records for accountability and tracking purposes.
11+
12+
## Installation Instructions
13+
1. **Clone the Repository**: Clone the repository to your local machine.
14+
```
15+
git clone <repository-url>
16+
```
17+
2. **Install Dependencies**: Ensure that you have Odoo installed and running. Install any required Python packages.
18+
3. **Add the Module**: Place the `records_management` directory in your Odoo addons path.
19+
4. **Update the App List**: In the Odoo interface, go to Apps and click on "Update Apps List".
20+
5. **Install the Module**: Search for "Records Management" in the Apps menu and click "Install".
21+
22+
## Usage
23+
- **Creating Pickup Requests**: Navigate to the Pickup Requests menu to create new requests for items.
24+
- **Managing Shredding Services**: Access the Shredding Services menu to log and track shredding activities.
25+
- **Viewing Inventory**: Use the Inventory menu to view and manage stock items associated with customers.
26+
27+
## Security
28+
The module includes security settings to manage access rights for different user groups, ensuring that only authorized personnel can perform sensitive actions.
29+
30+
## JavaScript Functionality
31+
The module integrates JavaScript for enhanced user interaction, including barcode scanning capabilities for quick item identification.
32+
33+
## Support
34+
For any issues or feature requests, please open an issue in the repository or contact the module maintainer.

records_management-1/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
from . import models
2+
from . import controllers
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "Records Management",
3+
"version": "1.0",
4+
"category": "Inventory",
5+
"summary": "Module for managing records and shredding services.",
6+
"description": "This module provides functionalities for managing stock production lots, shredding services, and pickup requests, including customer references and audit logging.",
7+
"author": "Your Name",
8+
"website": "https://yourwebsite.com",
9+
"depends": [
10+
"base",
11+
"stock",
12+
"sale",
13+
"web"
14+
],
15+
"data": [
16+
"security/ir.model.access.csv",
17+
"security/security.xml",
18+
"data/scrm_records_management_data.xml",
19+
"views/scrm_records_management_views.xml",
20+
"views/scrm_records_management_templates.xml",
21+
"views/assets.xml"
22+
],
23+
"installable": true,
24+
"application": false,
25+
"auto_install": false
26+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# File: /records_management/records_management/controllers/__init__.py
2+
3+
from . import scrm_records_management_controller
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from odoo import http
2+
from odoo.http import request
3+
from odoo.exceptions import AccessError, ValidationError
4+
from odoo import _
5+
6+
class ScrmRecordsManagementController(http.Controller):
7+
8+
@http.route('/my/inventory', type='http', auth='user', website=True)
9+
def inventory(self, **kw):
10+
partner = request.env.user.partner_id
11+
if not partner:
12+
raise AccessError(_("No partner associated with this user."))
13+
14+
serials = request.env['stock.production.lot'].search([('customer_id', '=', partner.id)])
15+
quants = request.env['stock.quant'].search([('lot_id', 'in', serials.ids), ('location_id.usage', '=', 'internal')])
16+
17+
return request.render('records_management.inventory_template', {'quants': quants})
18+
19+
@http.route('/my/request_pickup', type='http', auth='user', website=True, methods=['GET', 'POST'])
20+
def request_pickup(self, **post):
21+
partner = request.env.user.partner_id
22+
error = None
23+
24+
if request.httprequest.method == 'POST':
25+
try:
26+
raw_ids = request.httprequest.form.getlist('item_ids')
27+
item_ids = [int(id) for id in raw_ids if id.isdigit()]
28+
if not item_ids:
29+
error = _("Please select at least one item for pickup.")
30+
else:
31+
request.env['pickup.request'].sudo().create_pickup_request(partner, item_ids)
32+
return request.redirect('/my/inventory')
33+
except (ValidationError, Exception) as e:
34+
error = str(e)
35+
36+
serials = request.env['stock.production.lot'].search([('customer_id', '=', partner.id)])
37+
return request.render('records_management.pickup_request_form', {
38+
'serials': serials,
39+
'error': error,
40+
'pickup_item_ids_field': 'item_ids',
41+
'partner': partner,
42+
'pickup_request': request.env['pickup.request'].new({
43+
'customer_id': partner.id,
44+
'item_ids': [(6, 0, [])]
45+
}),
46+
})
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<record id="shredding_service_product" model="product.template">
2+
<field name="name">Shredding Service</field>
3+
<field name="type">service</field>
4+
<field name="categ_id" ref="product.product_category_all"/>
5+
<field name="list_price">50.0</field>
6+
<field name="uom_id" ref="product.product_uom_hour"/>
7+
</record>
8+
9+
<record id="shredding_bin_product" model="product.template">
10+
<field name="name">Shredding Bin</field>
11+
<field name="type">product</field>
12+
<field name="categ_id" ref="product.product_category_all"/>
13+
<field name="list_price">100.0</field>
14+
<field name="uom_id" ref="product.product_uom_unit"/>
15+
</record>
16+
17+
<record id="pickup_request_email_template" model="mail.template">
18+
<field name="name">Pickup Request Notification</field>
19+
<field name="model_id" ref="model_pickup_request"/>
20+
<field name="email_from">${(object.customer_id.email or '')|safe}</field>
21+
<field name="subject">Pickup Request Confirmation</field>
22+
<field name="body_html"><![CDATA[
23+
<p>Dear ${object.customer_id.name},</p>
24+
<p>Your pickup request has been successfully created.</p>
25+
<p>Request Date: ${object.request_date}</p>
26+
<p>Items for Pickup: ${object.item_ids.mapped('name')}</p>
27+
<p>Thank you!</p>
28+
]]></field>
29+
</record>
30+
31+
<record id="shredding_service_action" model="ir.actions.server">
32+
<field name="name">Send Pickup Request Email</field>
33+
<field name="model_id" ref="model_pickup_request"/>
34+
<field name="state">code</field>
35+
<field name="code">
36+
action = env['mail.template'].browse(ref('pickup_request_email_template')).send_mail(record.id, force_send=True)
37+
</field>
38+
</record>
39+
40+
<record id="shredding_service_cron" model="ir.cron">
41+
<field name="name">Send Pickup Request Emails</field>
42+
<field name="model_id" ref="model_pickup_request"/>
43+
<field name="state">code</field>
44+
<field name="code">model.send_pickup_request_emails()</field>
45+
<field name="interval_number">1</field>
46+
<field name="interval_type">days</field>
47+
<field name="numbercall">-1</field>
48+
<field name="doall" eval="False"/>
49+
</record>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import scrm_records_management
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
"""
2+
Odoo manifest dictionary has been removed from this Python file.
3+
Please place the manifest dictionary in a separate __manifest__.py file as required by Odoo module structure.
4+
"""
5+
from odoo import fields, models, api, _
6+
from odoo.exceptions import ValidationError, AccessError
7+
from odoo import http
8+
from odoo.http import request
9+
10+
# Constant for the pickup request form field name
11+
PICKUP_ITEM_IDS_FIELD = 'item_ids'
12+
13+
class StockProductionLot(models.Model):
14+
_inherit = 'stock.production.lot'
15+
16+
customer_id = fields.Many2one('res.partner', string='Customer')
17+
18+
class ShreddingService(models.Model):
19+
_name = 'shredding.service'
20+
_description = 'Document Shredding Service'
21+
22+
service_date = fields.Date(string='Service Date', default=lambda self: fields.Date.today())
23+
customer_id = fields.Many2one('res.partner', string='Customer', required=True)
24+
service_type = fields.Selection([
25+
('bin', 'Bin Shredding'),
26+
('box', 'Box Shredding')
27+
], string='Service Type', required=True)
28+
bin_ids = fields.Many2many('stock.production.lot', string='Serviced Bins',
29+
domain=[('product_id.name', '=', 'Shredding Bin')])
30+
box_quantity = fields.Integer(string='Number of Boxes', default=0)
31+
shredded_box_ids = fields.Many2many('stock.production.lot', string='Shredded Boxes',
32+
domain=[('customer_id', '!=', False)])
33+
audit_barcodes = fields.Text(string='Audit Barcodes')
34+
total_charge = fields.Float(string='Total Charge', compute='_compute_total_charge')
35+
timestamp = fields.Datetime(string='Service Timestamp', default=lambda self: fields.Datetime.now())
36+
latitude = fields.Float(string='Latitude')
37+
longitude = fields.Float(string='Longitude')
38+
attachment_ids = fields.Many2many('ir.attachment', string='Attachments')
39+
map_display = fields.Char(compute='_compute_map_display', string='Map')
40+
41+
@api.constrains('box_quantity')
42+
def _check_box_quantity(self):
43+
for rec in self:
44+
if rec.service_type == 'box' and (rec.box_quantity is None or rec.box_quantity < 1):
45+
raise ValidationError(_("Box quantity must be a positive integer for box shredding."))
46+
47+
@api.constrains('latitude', 'longitude')
48+
def _check_lat_long(self):
49+
for rec in self:
50+
if rec.latitude and not (-90 <= rec.latitude <= 90):
51+
raise ValidationError(_("Latitude must be between -90 and 90."))
52+
if rec.longitude and not (-180 <= rec.longitude <= 180):
53+
raise ValidationError(_("Longitude must be between -180 and 180."))
54+
55+
@api.depends('service_type', 'bin_ids', 'box_quantity', 'shredded_box_ids')
56+
def _compute_total_charge(self):
57+
for record in self:
58+
if record.service_type == 'bin':
59+
record.total_charge = len(record.bin_ids) * 10.0
60+
else:
61+
qty = record.box_quantity or len(record.shredded_box_ids) or 0
62+
record.total_charge = qty * 5.0
63+
64+
@api.depends('latitude', 'longitude')
65+
def _compute_map_display(self):
66+
for record in self:
67+
record.map_display = f"{record.latitude},{record.longitude}"
68+
69+
class PickupRequest(models.Model):
70+
_name = 'pickup.request'
71+
_description = 'Pickup Request'
72+
73+
customer_id = fields.Many2one('res.partner', string='Customer', required=True)
74+
request_date = fields.Date(string='Request Date', default=fields.Date.today)
75+
state = fields.Selection([
76+
('draft', 'Draft'),
77+
('submitted', 'Submitted'),
78+
('approved', 'Approved'),
79+
('done', 'Done'),
80+
('cancel', 'Cancelled'),
81+
], default='draft', string='Status')
82+
item_ids = fields.Many2many('stock.production.lot', string='Items',
83+
domain="[('customer_id', '=', customer_id)]")
84+
85+
@api.model
86+
def create_pickup_request(self, partner, item_ids):
87+
if not item_ids:
88+
raise ValidationError(_("No items selected for pickup."))
89+
items = self.env['stock.production.lot'].search([
90+
('id', 'in', item_ids),
91+
('customer_id', '=', partner.id)
92+
])
93+
if not items:
94+
raise ValidationError(_("Selected items are invalid or do not belong to you."))
95+
return self.create({
96+
'customer_id': partner.id,
97+
'item_ids': [(6, 0, items.ids)],
98+
})
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
2+
access_pickup_request,access_pickup_request,model_pickup_request,,1,1,1,1
3+
access_shredding_service,access_shredding_service,model_shredding_service,,1,1,1,1
4+
access_stock_production_lot,access_stock_production_lot,model_stock_production_lot,,1,1,1,1
5+
access_inventory_portal,access_inventory_portal,model_inventory_portal,,1,1,1,1
6+
access_audit_log,access_audit_log,model_audit_log,,1,1,1,1
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<record id="group_records_manager" model="res.groups">
2+
<field name="name">Records Manager</field>
3+
<field name="category_id" ref="base.module_category_hidden"/>
4+
</record>
5+
6+
<record id="group_shredding_technician" model="res.groups">
7+
<field name="name">Shredding Technician</field>
8+
<field name="category_id" ref="base.module_category_hidden"/>
9+
</record>
10+
11+
<record id="model_pickup_request_access" model="ir.model.access">
12+
<field name="name">pickup.request access</field>
13+
<field name="model_id" ref="model_pickup_request"/>
14+
<field name="group_id" ref="group_records_manager"/>
15+
<field name="perm_read" eval="1"/>
16+
<field name="perm_write" eval="1"/>
17+
<field name="perm_create" eval="1"/>
18+
<field name="perm_unlink" eval="1"/>
19+
</record>
20+
21+
<record id="model_shredding_service_access" model="ir.model.access">
22+
<field name="name">shredding.service access</field>
23+
<field name="model_id" ref="model_shredding_service"/>
24+
<field name="group_id" ref="group_shredding_technician"/>
25+
<field name="perm_read" eval="1"/>
26+
<field name="perm_write" eval="1"/>
27+
<field name="perm_create" eval="1"/>
28+
<field name="perm_unlink" eval="1"/>
29+
</record>

0 commit comments

Comments
 (0)