1+
2+ # (Odoo manifest dictionary removed from Python file. Place it in __manifest__.py instead.)
3+ from odoo import fields , models , api
4+
5+ class StockProductionLot (models .Model ):
6+ _inherit = 'stock.production.lot'
7+
8+ # Reference to the customer (res.rtner) associated with this lot.
9+ customer_id = fields .Many2one ('res.rtner' , string = 'Customer' )
10+
11+ class ShreddingService (models .Model ):
12+ _name = 'shredding.service'
13+ _description = 'Document Shredding Service'
14+
15+ customer_id = fields .Many2one ('res.rtner' , string = 'Customer' , required = True )
16+ service_date = fields .Date (string = 'Service Date' , default = fields .Date .today )
17+ service_type = fields .Selection ([
18+ ('bin' , 'Bin Shredding' ),
19+ ('box' , 'Box Shredding' )
20+ ], string = 'Service Type' , required = True )
21+ bin_ids = fields .Many2many ('stock.production.lot' , string = 'Serviced Bins' ,
22+ domain = [('product_id.name' , '=' , 'Shredding Bin' )])
23+ box_quantity = fields .Integer (string = 'Number of Boxes' )
24+ shredded_box_ids = fields .Many2many ('stock.production.lot' , string = 'Shredded Boxes' ,
25+ domain = [('customer_id' , '!=' , False )])
26+ audit_barcodes = fields .Text (string = 'Audit Barcodes' )
27+ total_charge = fields .Float (string = 'Total Charge' , compute = '_compute_total_charge' )
28+ timestamp = fields .Datetime (string = 'Service Timestamp' , default = fields .Datetime .now )
29+ latitude = fields .Float (string = 'Latitude' )
30+ longitude = fields .Float (string = 'Longitude' )
31+ attachment_ids = fields .Many2many ('ir.attachment' , string = 'Attachments' )
32+ map_display = fields .Char (compute = '_compute_map_display' , string = 'Map' )
33+
34+ @api .depends ('service_type' , 'bin_ids' , 'box_quantity' , 'shredded_box_ids' )
35+ def _compute_total_charge (self ):
36+ for record in self :
37+ if record .service_type == 'bin' :
38+ record .total_charge = len (record .bin_ids ) * 10.0
39+ else :
40+ qty = record .box_quantity or len (record .shredded_box_ids )
41+ record .total_charge = qty * 5.0
42+
43+ @api .depends ('latitude' , 'longitude' )
44+ def _compute_map_display (self ):
45+ for record in self :
46+ record .map_display = f"{ record .latitude } ,{ record .longitude } "
47+
48+ class PickupRequest (models .Model ):
49+ """
50+ Represents a pickup request for items associated with a customer.
51+
52+ Model Fields:
53+ customer_id (Many2one): Reference to the customer (res.rtner) making the pickup request. Required.
54+ request_date (Date): The date the pickup request was created. Defaults to today's date.
55+ state (Selection): The current status of the pickup request. Possible values are:
56+ - 'draft': Draft
57+ - 'confirmed': Confirmed
58+ - 'done': Done
59+ Defaults to 'draft'.
60+ item_ids (Many2many): List of items (stock.production.lot) included in the pickup request.
61+ Only items belonging to the selected customer can be chosen.
62+ """
63+ _name = 'pickup.request'
64+ _description = 'Pickup Request'
65+
66+ customer_id = fields .Many2one ('res.rtner' , string = 'Customer' , required = True )
67+ request_date = fields .Date (string = 'Request Date' , default = fields .Date .today )
68+ state = fields .Selection ([
69+ ('draft' , 'Draft' ),
70+ ('confirmed' , 'Confirmed' ),
71+ ('done' , 'Done' )
72+ ], default = 'draft' , string = 'Status' )
73+ item_ids = fields .Many2many ('stock.production.lot' , string = 'Items' ,
74+ domain = "[('customer_id', '=', customer_id)]" )
75+
76+ from odoo import http
77+ from odoo .http import request
78+
79+ class InventoryPortal (http .Controller ):
80+ @http .route ('/my/inventory' , type = 'http' , auth = 'user' , website = True )
81+ def inventory (self , ** kw ):
82+ """
83+ Retrieves and renders the inventory of stock quants associated with the current user's rtner.
84+
85+ This method performs the following steps:
86+ 1. Retrieves the current user's rtner record.
87+ 2. Searches for all stock production lots (serial numbers) linked to the rtner as a customer.
88+ 3. Searches for all stock quants associated with the found serials and located in internal locations.
89+ 4. Renders the 'records_management.inventory_template' template, ssing the filtered quants as context.
90+
91+ Keyword Args:
92+ **kw: Arbitrary keyword arguments (not used).
93+
94+ Returns:
95+ werkzeug.wrappers.Response: The rendered inventory template with the relevant stock quants.
96+ """
97+ rtner = request .env .user .rtner_id
98+ serials = request .env ['stock.production.lot' ].search ([('customer_id' , '=' , rtner .id )])
99+ quants = request .env ['stock.quant' ].search ([
100+ ('lot_id' , 'in' , serials .ids ),
101+ ('location_id.usage' , '=' , 'internal' )
102+ ])
103+ return request .render ('records_management.inventory_template' , {'quants' : quants })
104+
105+ @http .route ('/my/request_pickup' , type = 'http' , auth = 'user' , website = True )
106+ def request_pickup (self , ** post ):
107+ rtner = request .env .user .rtner_id
108+ if request .httprequest .method == 'POST' :
109+ item_ids = [int (id ) for id in request .httprequest .form .getlist ('item_ids' )]
110+ items = request .env ['stock.production.lot' ].search ([
111+ ('id' , 'in' , item_ids ),
112+ ('customer_id' , '=' , rtner .id )
113+ ])
114+ if items :
115+ request .env ['pickup.request' ].create ({
116+ 'customer_id' : rtner .id ,
117+ 'item_ids' : [(6 , 0 , items .ids )],
118+ })
119+ return request .redirect ('/my/inventory' )
120+ # Render the pickup request form for GET requests
121+ serials = request .env ['stock.production.lot' ].search ([('customer_id' , '=' , rtner .id )])
122+ return request .render ('records_management.pickup_request_form' , {'serials' : serials })
123+
0 commit comments