Skip to content

Commit a2e4ad9

Browse files
Merge pull request #4 from John75SunCity/main
KG
2 parents ad63d24 + 675ea9b commit a2e4ad9

26 files changed

+719
-0
lines changed

.devcontainer/devcontainer.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"features": {
3+
"ghcr.io/devcontainers/features/docker-outside-of-docker:1": {}
4+
}
5+
}
File renamed without changes.

.vscode/launch.json

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
// Use IntelliSense to learn about possible attributes.
3+
// Hover to view descriptions of existing attributes.
4+
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5+
"version": "0.2.0",
6+
"configurations": [
7+
{
8+
"name": "Python Debugger: Current File",
9+
"type": "debugpy",
10+
"request": "launch",
11+
"program": "${file}",
12+
"console": "integratedTerminal"
13+
}
14+
]
15+
}

.vscode/settings.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
{
2+
"python.analysis.typeCheckingMode": "basic",
3+
"python.analysis.extraPaths": [
4+
"/workspaces/ssh-git-github.com-odoo-odoo.git-8.0"
5+
]
6+
}

HTTP 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+
import logging
3+
4+
_logger = logging.getLogger(__name__)
5+
6+
CUSTOMER_FIELD = 'customer_id'
7+
INTERNAL_USAGE = 'internal'
8+
9+
10+
class MyController(http.Controller):
11+
12+
def _get_partner_inventory(self, partner):
13+
serials = http.request.env['stock.production.lot'].search([(CUSTOMER_FIELD, '=', partner.id)])
14+
return http.request.env['stock.quant'].search([
15+
('lot_id', 'in', serials.ids),
16+
('location_id.usage', '=', INTERNAL_USAGE)
17+
])
18+
19+
@http.route('/my/inventory/request_pickup', type='http', auth='user', methods=['POST'], csrf=True)
20+
def request_pickup(self, **kw):
21+
user = http.request.env.user
22+
partner = user.partner_id
23+
_logger.info('Inventory accessed by partner %s', partner.id)
24+
try:
25+
item_ids = [int(id) for id in http.request.httprequest.form.getlist('item_ids')]
26+
except ValueError:
27+
_logger.warning("User %s (ID: %s) provided invalid item_ids: %s", user.login, user.id, http.request.httprequest.form.getlist('item_ids'))
28+
return http.request.redirect('/my/inventory?error=invalid_item_ids')
29+
_logger.info('Pickup requested for items %s by partner %s', item_ids, partner.id)
30+
# ...existing code...
31+
32+
@http.route('/my/inventory', type='http', auth='user', website=True, methods=['GET'], csrf=True)
33+
def my_inventory(self, **kw):
34+
user = http.request.env.user
35+
partner = user.partner_id
36+
quants = self._get_partner_inventory(partner)
37+
return http.request.render(
38+
'records_management.inventory_template',
39+
{
40+
'quants': quants,
41+
'message': 'No inventory items found.' if not quants else ''
42+
}
43+
)
44+
45+
# ...existing code...
46+

__manifest__.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
'name': 'Records Management',
3+
'version': '1.0',
4+
'depends': ['stock', 'web'],
5+
'data': [
6+
'views/inventory_template.xml',
7+
'views/pickup_request_form.xml',
8+
],
9+
'installable': True,
10+
'application': True,
11+
}

docker-compose.yml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
version: '2'
2+
services:
3+
db:
4+
image: postgres:10
5+
environment:
6+
- POSTGRES_DB=postgres
7+
- POSTGRES_USER=odoo
8+
- POSTGRES_PASSWORD=odoo
9+
restart: always
10+
11+
odoo:
12+
image: odoo:8.0
13+
depends_on:
14+
- db
15+
ports:
16+
- "8069:8069"
17+
volumes:
18+
- ./records_management:/mnt/extra-addons/records_management
19+
environment:
20+
- HOST=db
21+
- USER=odoo
22+
- PASSWORD=odoo
23+
restart: always

records_management/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import models

records_management/__manifest__.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
from .. import models
2+
3+
{
4+
'name': 'Records Management',
5+
'version': '1.0',
6+
'depends': ['stock', 'web'],
7+
'data': [
8+
'views/inventory_template.xml',
9+
'views/pickup_request_form.xml',
10+
'views/your_view1.xml',
11+
'views/your_view2.xml',
12+
'security/ir.model.access.csv',
13+
],
14+
'installable': True,
15+
'application': True,
16+
}
17+
# Odoo manifest dictionary should be in __manifest__.py, not here.
18+
from odoo import fields, models, api, http
19+
from odoo.http import request
20+
21+
class StockProductionLot(models.Model):
22+
_inherit = 'stock.production.lot'
23+
24+
# Reference to the customer (res.partner) associated with this lot.
25+
customer_id = fields.Many2one('res.partner', string='Customer')
26+
27+
class ShreddingService(models.Model):
28+
_name = 'shredding.service'
29+
_description = 'Document Shredding Service'
30+
31+
customer_id = fields.Many2one('res.partner', string='Customer', required=True)
32+
service_date = fields.Date(string='Service Date', default=fields.Date.today)
33+
service_type = fields.Selection([
34+
('bin', 'Bin Shredding'),
35+
('box', 'Box Shredding')
36+
], string='Service Type', required=True)
37+
bin_ids = fields.Many2many(
38+
'stock.production.lot', string='Serviced Bins',
39+
domain=[('product_id.name', '=', 'Shredding Bin')]
40+
)
41+
box_quantity = fields.Integer(string='Number of Boxes')
42+
shredded_box_ids = fields.Many2many(
43+
'stock.production.lot', string='Shredded Boxes',
44+
domain=[('customer_id', '!=', False)]
45+
)
46+
audit_barcodes = fields.Text(string='Audit Barcodes')
47+
total_charge = fields.Float(string='Total Charge', compute='_compute_total_charge')
48+
timestamp = fields.Datetime(string='Service Timestamp', default=fields.Datetime.now)
49+
latitude = fields.Float(string='Latitude')
50+
longitude = fields.Float(string='Longitude')
51+
attachment_ids = fields.Many2many('ir.attachment', string='Attachments')
52+
map_display = fields.Char(compute='_compute_map_display', string='Map')
53+
54+
@api.depends('service_type', 'bin_ids', 'box_quantity', 'shredded_box_ids')
55+
def _compute_total_charge(self):
56+
for record in self:
57+
if record.service_type == 'bin':
58+
record.total_charge = len(record.bin_ids) * 10.0
59+
elif record.service_type == 'box':
60+
qty = record.box_quantity or len(record.shredded_box_ids)
61+
record.total_charge = qty * 5.0
62+
else:
63+
record.total_charge = 0.0
64+
65+
@api.depends('latitude', 'longitude')
66+
def _compute_map_display(self):
67+
for record in self:
68+
record.map_display = f"{record.latitude},{record.longitude}"
69+
70+
class PickupRequest(models.Model):
71+
"""
72+
Represents a pickup request for items associated with a customer.
73+
74+
Model Fields:
75+
customer_id (Many2one): Reference to the customer (res.partner) making the pickup request. Required.
76+
request_date (Date): The date the pickup request was created. Defaults to today's date.
77+
state (Selection): The current status of the pickup request. Possible values are:
78+
- 'draft': Draft
79+
- 'confirmed': Confirmed
80+
- 'done': Done
81+
Defaults to 'draft'.
82+
item_ids (Many2many): List of items (stock.production.lot) included in the pickup request.
83+
Only items belonging to the selected customer can be chosen.
84+
"""
85+
_name = 'pickup.request'
86+
_description = 'Pickup Request'
87+
88+
customer_id = fields.Many2one('res.partner', string='Customer', required=True)
89+
request_date = fields.Date(string='Request Date', default=fields.Date.today)
90+
state = fields.Selection([
91+
('draft', 'Draft'),
92+
('confirmed', 'Confirmed'),
93+
('done', 'Done')
94+
], default='draft', string='Status')
95+
item_ids = fields.Many2many(
96+
'stock.production.lot', string='Items',
97+
domain="[('customer_id', '=', customer_id)]"
98+
)
99+
100+
class InventoryPortal(http.Controller):
101+
@http.route('/my/inventory', type='http', auth='user', website=True)
102+
def inventory(self, **kw):
103+
"""
104+
Retrieves and renders the inventory of stock quants associated with the current user's partner.
105+
106+
Returns:
107+
werkzeug.wrappers.Response: The rendered inventory template with the relevant stock quants.
108+
"""
109+
partner = request.env.user.partner_id
110+
if not partner:
111+
return request.not_found()
112+
serials = request.env['stock.production.lot'].search([('customer_id', '=', partner.id)])
113+
quants = request.env['stock.quant'].search([
114+
('lot_id', 'in', serials.ids),
115+
('location_id.usage', '=', 'internal')
116+
])
117+
return request.render('records_management.inventory_template', {'quants': quants})
118+
119+
@http.route('/my/request_pickup', type='http', auth='user', website=True, methods=['GET', 'POST'], csrf=True)
120+
def request_pickup(self, **post):
121+
partner = request.env.user.partner_id
122+
if not partner:
123+
return request.not_found()
124+
if request.httprequest.method == 'POST':
125+
item_ids = request.httprequest.form.getlist('item_ids')
126+
try:
127+
item_ids = [int(id) for id in item_ids]
128+
except (ValueError, TypeError):
129+
item_ids = []
130+
items = request.env['stock.production.lot'].search([
131+
('id', 'in', item_ids),
132+
('customer_id', '=', partner.id)
133+
])
134+
if items:
135+
request.env['pickup.request'].create({
136+
'customer_id': partner.id,
137+
'item_ids': [(6, 0, items.ids)],
138+
})
139+
return request.redirect('/my/inventory')
140+
# Render the pickup request form for GET requests
141+
serials = request.env['stock.production.lot'].search([('customer_id', '=', partner.id)])
142+
return request.render('records_management.pickup_request_form', {'serials': serials})
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from . import portal

0 commit comments

Comments
 (0)