Skip to content

Commit ec14520

Browse files
author
John75SunCity
committed
feat: Add default shredding bin products with auto-select by size
- Created shredding_bin_products_data.xml with 6 products: - 23 Gallon (), 32 Gallon Bin (), 32 Gallon Console () - 64 Gallon (), 96 Gallon (), Generic Fallback () - Updated _compute_product_from_size() to use XML refs - Products auto-select when bin_size is set on shredding.service.bin - Enables proper billing with bin-specific pricing
1 parent 81e7910 commit ec14520

File tree

3 files changed

+132
-22
lines changed

3 files changed

+132
-22
lines changed

records_management/__manifest__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@
113113
"data/naid_configurator_data.xml",
114114
"data/document_retrieval_rates_data.xml",
115115
"data/products_data.xml",
116+
"data/shredding_bin_products_data.xml", # Default products for each bin size
116117
"data/storage_fee_data.xml",
117118
"data/container_bulk_actions.xml", # Bulk actions for container management
118119

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<odoo>
3+
<data noupdate="1">
4+
<!--
5+
============================================================================
6+
SHREDDING BIN SERVICE PRODUCTS
7+
============================================================================
8+
Default products for each bin size used in shredding service billing.
9+
These products are auto-linked to shredding.service.bin records via bin_size.
10+
11+
Pricing is base/list price - customers may have negotiated rates that override.
12+
============================================================================
13+
-->
14+
15+
<!-- Product Category for Shredding Services -->
16+
<record id="product_category_shredding_services" model="product.category">
17+
<field name="name">Shredding Bin Services</field>
18+
<field name="parent_id" ref="product.product_category_all"/>
19+
</record>
20+
21+
<!-- 23 Gallon Shredinator Service -->
22+
<record id="product_shredding_bin_23" model="product.product">
23+
<field name="name">23 Gallon Shredinator Service</field>
24+
<field name="default_code">SHRED-23</field>
25+
<field name="type">service</field>
26+
<field name="categ_id" ref="product_category_shredding_services"/>
27+
<field name="list_price">20.00</field>
28+
<field name="is_records_management_product">True</field>
29+
<field name="sale_ok">True</field>
30+
<field name="purchase_ok">False</field>
31+
<field name="description_sale">Shredding service for 23 Gallon Shredinator bin. Includes secure pickup and NAID-compliant destruction.</field>
32+
<field name="invoice_policy">order</field>
33+
</record>
34+
35+
<!-- 32 Gallon Bin Service -->
36+
<record id="product_shredding_bin_32g" model="product.product">
37+
<field name="name">32 Gallon Bin Service</field>
38+
<field name="default_code">SHRED-32G</field>
39+
<field name="type">service</field>
40+
<field name="categ_id" ref="product_category_shredding_services"/>
41+
<field name="list_price">35.00</field>
42+
<field name="is_records_management_product">True</field>
43+
<field name="sale_ok">True</field>
44+
<field name="purchase_ok">False</field>
45+
<field name="description_sale">Shredding service for 32 Gallon standard bin. Includes secure pickup and NAID-compliant destruction.</field>
46+
<field name="invoice_policy">order</field>
47+
</record>
48+
49+
<!-- 32 Gallon Console Service -->
50+
<record id="product_shredding_bin_32c" model="product.product">
51+
<field name="name">32 Gallon Console Service</field>
52+
<field name="default_code">SHRED-32C</field>
53+
<field name="type">service</field>
54+
<field name="categ_id" ref="product_category_shredding_services"/>
55+
<field name="list_price">30.00</field>
56+
<field name="is_records_management_product">True</field>
57+
<field name="sale_ok">True</field>
58+
<field name="purchase_ok">False</field>
59+
<field name="description_sale">Shredding service for 32 Gallon console-style bin. Includes secure pickup and NAID-compliant destruction.</field>
60+
<field name="invoice_policy">order</field>
61+
</record>
62+
63+
<!-- 64 Gallon Bin Service -->
64+
<record id="product_shredding_bin_64" model="product.product">
65+
<field name="name">64 Gallon Bin Service</field>
66+
<field name="default_code">SHRED-64</field>
67+
<field name="type">service</field>
68+
<field name="categ_id" ref="product_category_shredding_services"/>
69+
<field name="list_price">65.00</field>
70+
<field name="is_records_management_product">True</field>
71+
<field name="sale_ok">True</field>
72+
<field name="purchase_ok">False</field>
73+
<field name="description_sale">Shredding service for 64 Gallon bin. Includes secure pickup and NAID-compliant destruction.</field>
74+
<field name="invoice_policy">order</field>
75+
</record>
76+
77+
<!-- 96 Gallon Bin Service -->
78+
<record id="product_shredding_bin_96" model="product.product">
79+
<field name="name">96 Gallon Bin Service</field>
80+
<field name="default_code">SHRED-96</field>
81+
<field name="type">service</field>
82+
<field name="categ_id" ref="product_category_shredding_services"/>
83+
<field name="list_price">95.00</field>
84+
<field name="is_records_management_product">True</field>
85+
<field name="sale_ok">True</field>
86+
<field name="purchase_ok">False</field>
87+
<field name="description_sale">Shredding service for 96 Gallon bin. Includes secure pickup and NAID-compliant destruction.</field>
88+
<field name="invoice_policy">order</field>
89+
</record>
90+
91+
<!-- Generic/Default Shredding Service (fallback) -->
92+
<record id="product_shredding_service" model="product.product">
93+
<field name="name">Shredding Service</field>
94+
<field name="default_code">SHRED-GEN</field>
95+
<field name="type">service</field>
96+
<field name="categ_id" ref="product_category_shredding_services"/>
97+
<field name="list_price">35.00</field>
98+
<field name="is_records_management_product">True</field>
99+
<field name="sale_ok">True</field>
100+
<field name="purchase_ok">False</field>
101+
<field name="description_sale">General shredding service. Used as fallback when specific bin size product is not available.</field>
102+
<field name="invoice_policy">order</field>
103+
</record>
104+
105+
</data>
106+
</odoo>

records_management/models/shredding_service_bin.py

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -506,34 +506,37 @@ def _compute_billing_rates(self):
506506

507507
@api.depends('bin_size')
508508
def _compute_product_from_size(self):
509-
"""Auto-select product based on bin size for invoicing."""
510-
# Build mapping of bin size to product (search once per bin size)
511-
size_products = {}
509+
"""Auto-select product based on bin size for invoicing using XML refs."""
510+
# Map bin sizes to XML IDs for reliable lookup
511+
size_to_xmlid = {
512+
'23': 'records_management.product_shredding_bin_23',
513+
'32g': 'records_management.product_shredding_bin_32g',
514+
'32c': 'records_management.product_shredding_bin_32c',
515+
'64': 'records_management.product_shredding_bin_64',
516+
'96': 'records_management.product_shredding_bin_96',
517+
}
518+
fallback_xmlid = 'records_management.product_shredding_service'
519+
520+
# Cache products to avoid repeated lookups
521+
product_cache = {}
522+
512523
for record in self:
513524
if not record.bin_size:
514525
record.product_id = False
515526
continue
516527

517-
if record.bin_size not in size_products:
518-
# Search for product matching bin size
519-
# Convention: Product name contains bin size like "32 Gallon" or internal ref
520-
size_name_map = {
521-
'23': '23 Gallon',
522-
'32g': '32 Gallon Bin',
523-
'32c': '32 Gallon Console',
524-
'64': '64 Gallon',
525-
'96': '96 Gallon',
526-
}
527-
size_name = size_name_map.get(record.bin_size, '')
528-
product = self.env['product.product'].search([
529-
('is_records_management_product', '=', True),
530-
'|',
531-
('name', 'ilike', size_name),
532-
('default_code', '=', record.bin_size),
533-
], limit=1)
534-
size_products[record.bin_size] = product
528+
if record.bin_size not in product_cache:
529+
xmlid = size_to_xmlid.get(record.bin_size, fallback_xmlid)
530+
try:
531+
product = self.env.ref(xmlid, raise_if_not_found=False)
532+
if not product:
533+
# Fallback to generic shredding service
534+
product = self.env.ref(fallback_xmlid, raise_if_not_found=False)
535+
product_cache[record.bin_size] = product
536+
except Exception:
537+
product_cache[record.bin_size] = False
535538

536-
record.product_id = size_products.get(record.bin_size, False)
539+
record.product_id = product_cache.get(record.bin_size, False)
537540

538541
@api.depends('bin_size', 'current_customer_id')
539542
def _compute_price_per_service(self):

0 commit comments

Comments
 (0)