Skip to content

Commit 0077720

Browse files
Describe your changes
1 parent 30ba16c commit 0077720

File tree

6 files changed

+72
-30
lines changed

6 files changed

+72
-30
lines changed

.devcontainer/devcontainer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
"customizations": {
66
"vscode": {
77
"extensions": [
8-
"tht13.python"
8+
"tht13.python",
9+
"GitHub.copilot"
910
]
1011
}
1112
}

.vscode/extensions.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"recommendations": [
3+
"github.copilot"
4+
]
5+
}

records_management/models/pickup_request.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ class PickupRequest(models.Model):
2020
)
2121
request_date = fields.Date(
2222
string='Request Date',
23-
default=fields.Date.today,
23+
default=lambda self: fields.Date.today(),
2424
required=True,
2525
help="The date when the pickup is requested. Cannot be in the past."
2626
)
@@ -32,7 +32,6 @@ class PickupRequest(models.Model):
3232
item_ids = fields.Many2many(
3333
'stock.production.lot',
3434
string='Items',
35-
domain="[('customer_id', '=', customer_id)]",
3635
help="Items to be picked up. Only items belonging to the selected customer are allowed."
3736
)
3837

@@ -43,16 +42,19 @@ def _check_request_date(self):
4342
"""
4443
for rec in self:
4544
if rec.request_date and rec.request_date < fields.Date.today():
45+
if rec.request_date and fields.Date.from_string(rec.request_date) < fields.Date.from_string(fields.Date.today()):
4646
raise ValidationError("The request date cannot be in the past.")
47-
4847
@api.constrains('item_ids', 'customer_id')
4948
def _check_item_customer(self):
5049
"""
5150
Ensure all selected items belong to the selected customer.
5251
"""
5352
for rec in self:
5453
if rec.customer_id and rec.item_ids:
55-
invalid_items = rec.item_ids.filtered(lambda l: l.customer_id != rec.customer_id)
54+
invalid_items = rec.item_ids.search([
55+
('id', 'in', rec.item_ids.ids),
56+
('customer_id', '!=', rec.customer_id.id)
57+
])
5658
if invalid_items:
5759
raise ValidationError("All items must belong to the selected customer.")
5860

records_management/models/scrm_records_management.py

Lines changed: 24 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,15 @@
1-
# (Odoo manifest dictionary removed from Python file. Place it in __manifest__.py instead.)
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+
"""
25
from odoo import fields, models, api, _
36
from odoo.exceptions import ValidationError, AccessError
47
from odoo import http
58
from odoo.http import request
69

10+
# Constant for the pickup request form field name
11+
PICKUP_ITEM_IDS_FIELD = 'item_ids'
12+
713
class StockProductionLot(models.Model):
814
_inherit = 'stock.production.lot'
915

@@ -12,7 +18,7 @@ class StockProductionLot(models.Model):
1218

1319
class ShreddingService(models.Model):
1420
_name = 'shredding.service'
15-
_description = 'Document Shredding Service'
21+
service_date = fields.Date(string='Service Date', default=lambda self: fields.Date.today())
1622

1723
customer_id = fields.Many2one('res.partner', string='Customer', required=True)
1824
service_date = fields.Date(string='Service Date', default=fields.Date.today)
@@ -27,7 +33,7 @@ class ShreddingService(models.Model):
2733
domain=[('customer_id', '!=', False)])
2834
audit_barcodes = fields.Text(string='Audit Barcodes')
2935
total_charge = fields.Float(string='Total Charge', compute='_compute_total_charge')
30-
timestamp = fields.Datetime(string='Service Timestamp', default=fields.Datetime.now)
36+
timestamp = fields.Datetime(string='Service Timestamp', default=lambda self: fields.Datetime.now())
3137
latitude = fields.Float(string='Latitude')
3238
longitude = fields.Float(string='Longitude')
3339
attachment_ids = fields.Many2many('ir.attachment', string='Attachments')
@@ -59,7 +65,10 @@ def _compute_total_charge(self):
5965
if record.service_type == 'bin':
6066
record.total_charge = len(record.bin_ids) * 10.0
6167
else:
62-
qty = record.box_quantity or len(record.shredded_box_ids) or 0
68+
if record.box_quantity is not None:
69+
qty = record.box_quantity
70+
else:
71+
qty = len(record.shredded_box_ids) or 0
6372
record.total_charge = qty * 5.0
6473

6574
@api.depends('latitude', 'longitude')
@@ -90,8 +99,11 @@ class PickupRequest(models.Model):
9099
request_date = fields.Date(string='Request Date', default=fields.Date.today)
91100
state = fields.Selection([
92101
('draft', 'Draft'),
93-
('confirmed', 'Confirmed'),
94-
('done', 'Done')
102+
item_ids = fields.Many2many(
103+
'stock.production.lot',
104+
string='Items',
105+
domain=lambda self: [('customer_id', '=', self.customer_id.id)] if self.customer_id else []
106+
)
95107
], default='draft', string='Status')
96108
item_ids = fields.Many2many('stock.production.lot', string='Items',
97109
domain="[('customer_id', '=', customer_id)]")
@@ -180,7 +192,7 @@ def request_pickup(self, **post):
180192
if request.httprequest.method == 'POST':
181193
try:
182194
# Sanitize and validate item_ids
183-
raw_ids = request.httprequest.form.getlist('item_ids')
195+
raw_ids = request.httprequest.form.getlist(PICKUP_ITEM_IDS_FIELD)
184196
item_ids = [int(id) for id in raw_ids if id.isdigit()]
185197
if not item_ids:
186198
error = _("Please select at least one item for pickup.")
@@ -195,6 +207,11 @@ def request_pickup(self, **post):
195207
'serials': serials,
196208
'error': error
197209
})
210+
serials = self._get_serials(partner)
211+
return request.render('records_management.pickup_request_form', {
212+
'serials': serials,
213+
'error': error
214+
})
198215

199216
# --- Placeholders for test coverage (to be implemented in test modules) ---
200217
# def test_compute_total_charge(self): ...

records_management/models/stock_picking.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,30 @@ class StockPicking(models.Model):
44
_inherit = 'stock.picking'
55

66
def button_validate(self):
7+
"""
8+
Overrides the core button_validate to create a sale order for retrieval fees
9+
when an outgoing picking is validated and items are grouped by customer.
10+
"""
711
res = super().button_validate()
812
if self.state == 'done' and self.picking_type_id.code == 'outgoing':
9-
customer_items = self.move_line_ids.filtered(lambda ml: ml.lot_id and ml.lot_id.customer_id)
13+
# Filter move lines that have a lot with a customer
14+
customer_items = self.move_line_ids.filtered(lambda l: l.lot_id and l.lot_id.customer_id)
1015
if customer_items:
11-
customer = customer_items[0].lot_id.customer_id
12-
self.env['sale.order'].create({
13-
'partner_id': customer.id,
14-
'order_line': [(0, 0, {
15-
'product_id': self.env.ref('records_management.retrieval_fee_product').id,
16+
# Group items by customer
17+
customers = {}
18+
for item in customer_items:
19+
customer = item.lot_id.customer_id
20+
customers.setdefault(customer, []).append(item)
21+
for customer, items in customers.items():
22+
self.env['sale.order'].create({
23+
'partner_id': customer.id,
24+
'order_line': [(0, 0, {
25+
'product_id': self.env.ref('records_management.retrieval_fee_product').id,
26+
'product_uom_qty': len(items),
27+
})],
28+
})
29+
})],
30+
})
1631
'product_uom_qty': len(customer_items),
1732
})],
1833
})

records_management/models/stock_production_lot.py

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,17 @@
1-
from odoo import fields, models # type: ignore
1+
"""
2+
Developer Note:
3+
To optimize database queries, prefer using search_read or read_group instead of multiple .search() calls.
4+
Example:
5+
serials = request.env['stock.production.lot'].search_read(
6+
[('customer_id', '=', partner.id)], ['id']
7+
)
8+
quants = request.env['stock.quant'].search_read(
9+
[('lot_id', 'in', [s['id'] for s in serials]), ('location_id.usage', '=', 'internal')],
10+
['id', 'lot_id', 'location_id']
11+
)
12+
"""
13+
14+
from odoo import fields, models
215

316
class StockProductionLot(models.Model):
417
_inherit = 'stock.production.lot'
@@ -8,14 +21,3 @@ class StockProductionLot(models.Model):
821
string='Customer',
922
help='Tracks ownership. Customer-owned items (boxes, files) have a customer_id; company-owned bins may leave it empty or use it for assignment.'
1023
)
11-
12-
# Developer Note:
13-
# To optimize database queries, prefer using search_read or read_group instead of multiple .search() calls.
14-
# Example:
15-
# serials = request.env['stock.production.lot'].search_read(
16-
# [('customer_id', '=', partner.id)], ['id']
17-
# )
18-
# quants = request.env['stock.quant'].search_read(
19-
# [('lot_id', 'in', [s['id'] for s in serials]), ('location_id.usage', '=', 'internal')],
20-
# ['id', 'lot_id', 'location_id']
21-
# )

0 commit comments

Comments
 (0)