Simplify Brokerbin Product Uploads
Manually exporting inventory to Brokerbin becomes unsustainable once your product catalogue grows beyond a few dozen SKUs. Teams end up spending hours generating CSVs and double-checking quantities to keep listings accurate.
In this article, let’s walk you through a custom Brokerbin CSV export automation we built in Odoo 16. The solution automatically extracts in-stock products, applies Brokerbin condition codes, generates a Brokerbin-compatible CSV file, and refreshes it daily using a scheduled cron job.
This approach is ideal for IT distributors and electronics resellers who rely on Odoo to manage inventory and need a reliable way to synchronise listings with Brokerbin.
Overview of the Brokerbin Integration
Brokerbin is a B2B marketplace widely used for trading IT hardware components. While Odoo manages inventory effectively, it does not provide a native Brokerbin export. To bridge this gap, we built a custom Odoo module that:
- Filters products by configured categories and available stock
- Aggregates quantities and maps product conditions to Brokerbin codes
- Generates a Brokerbin-compliant CSV file
- Makes the file available for download directly from Odoo
- Schedules the export to run daily via a cron job
Configuring the Integration in Odoo
The integration is configurable from Settings > General Settings, allowing non-technical users to control the export behaviour.
| Field |
Description |
| Enable Brokerbin |
Turns the integration on or off |
| Categories |
Select product categories to include |
| Max Qty |
Limits the quantity per product in the export |
| CSV File URL |
Displays the download link for the generated CSV |
Settings Model Implementation
from odoo import models, fields, api
class ResConfigSettings(models.TransientModel):
_inherit = 'res.config.settings'
enable_brokerbin = fields.Boolean('Brokerbin Integration')
category_ids = fields.Many2many(
'product.category',
string="Categories",
required=True,
help="")
max_qty = fields.Integer(string='Max QTY to send')
csv_file_url = fields.Char('CSV file URL')
def set_values(self):
"""Set icecat settings values."""
super(ResConfigSettings, self).set_values()
params = self.env['ir.config_parameter'].sudo()
params.set_param('enable_brokerbin', self.enable_brokerbin)
params.set_param('category_ids', self.category_ids.ids)
params.set_param('max_qty', self.max_qty)
params.set_param('csv_file_url', self.csv_file_url)
@api.model
def get_values(self):
"""Retrieve icecat config data."""
res = super(ResConfigSettings, self).get_values()
params = self.env['ir.config_parameter'].sudo()
category_ids = params.get_param('category_ids', default='')
max_qty = params.get_param('max_qty', default=0)
category_ids = [int(x) for x in category_ids.replace('[', '').replace(']', '').split(',') if x]
res.update(
enable_brokerbin=params.get_param('enable_brokerbin'),
category_ids=[(6, 0, category_ids)],
max_qty=int(max_qty),
csv_file_url=params.get_param('csv_file_url')
)
return res
Here’s the XML snippet that extends the Odoo settings form:
<div class="o_setting_box">
<div class="o_setting_left_pane">
<field name="enable_brokerbin"/>
</div>
<div class="o_setting_right_pane">
<label for="enable_brokerbin"/>
<div class="text-muted">
Export Product info To Brokerbin
</div>
<div class="content-group" attrs="{'invisible': [('enable_brokerbin', '=', False)]}">
<div class="mt16 row">
<label for="category_ids" class="col-6 o_light_label"/>
<field name="category_ids" widget="many2many_tags"/>
<label for="max_qty" class="col-6 o_light_label"/>
<field name="max_qty"/>
<label for="csv_file_url" class="col-6 o_light_label"/>
<field name="csv_file_url" readonly="1"/>
</div>
</div>
</div>
</div>
Fetching Configured Products
The export process begins by retrieving products that match the configured categories and have available stock. Products explicitly excluded from Brokerbin are ignored.
The function _get_brokerbin_product_data() reads category IDs and max_qty values from system parameters and fetches all products with available stock (free_qty > 0).
def _get_brokerbin_product_data(self):
params = self.env['ir.config_parameter'].sudo()
category_ids = params.get_param('category_ids')
max_qty = params.get_param('max_qty')
category_ids = [int(x) for x in category_ids.replace('[', '').replace(']', '').split(',') if x]
products = self.search([
('free_qty', '>', 0),
('categ_id', 'in', category_ids),
('brokerbin_exclude', '=', False)
])
return products, float(max_qty) if max_qty else None
Aggregating Data for Brokerbin
Brokerbin requires products to be grouped by part number and condition code. Each product is mapped to Brokerbin’s condition code and grouped by (part_number, condition) for accurate aggregation.
def _aggregate_brokerbin_data(self, products, max_qty):
CONDITION_MAP = {
"New - Original Sealed Box": "F/S",
"New - Original Open Box": "NOB",
"Manufacturer Refurbished": "OEMREF",
"Seller Refurbished Excellent": "REF",
"Used": "USED",
}
aggregated = defaultdict(lambda: {
"manufacturer": "",
"condition_code": "",
"qty": 0.0,
"name": ""
})
for prod in products:
condition_name = prod.product_template_attribute_value_ids.product_attribute_value_id.name
condition_code = CONDITION_MAP.get(condition_name, "")
if not condition_code:
continue
qty = float(max_qty) if max_qty and prod.free_qty > max_qty else prod.free_qty
key = (prod.part_number or "", condition_code)
aggregated[key].update({
"manufacturer": prod.manufacturer.name if prod.manufacturer else "",
"condition_code": condition_code,
"qty": aggregated[key]["qty"] + qty,
"name": prod.name
})
return aggregated
Generating and Storing the CSV File
The aggregated data is then written to a CSV file and stored as an ir.attachment in Odoo.
If the file already exists, it’s updated; otherwise, a new file is created, and a public download URL is stored in system parameters.
def _generate_brokerbin_csv(self, aggregated):
csv_buffer = io.StringIO()
writer = csv.writer(csv_buffer)
writer.writerow(["Part Number", "Manufacturer", "Condition", "Price", "Quantity", "Description"])
for (part_number, condition_code), data in aggregated.items():
writer.writerow([part_number, data["manufacturer"], condition_code, "CALL", data["qty"], data["name"]])
csv_data = csv_buffer.getvalue()
csv_buffer.close()
filename = "brokerbin.csv"
base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
attachment = self.env["ir.attachment"].search([("name", "=", filename)], limit=1)
if attachment:
attachment.write({"datas": base64.b64encode(csv_data.encode("utf-8")), "mimetype": "text/csv"})
else:
attachment = self.env["ir.attachment"].create({
"type": 'binary',
"name": filename,
"datas": base64.b64encode(csv_data.encode("utf-8")),
"res_model": "product.product",
"mimetype": "text/csv",
"public": True
})
full_url = f"{base_url}/web/content/{attachment.id}?download=true"
self.env['ir.config_parameter'].sudo().set_param('csv_file_url', full_url)
Automating the Export with a Cron Job
A daily schedule action (cron job) triggers the export process automatically.
<record id="ir_cron_generate_brokerbin_csv" model="ir.cron">
<field name="name">Generate Brokerbin CSV</field>
<field name="active">True</field>
<field name="user_id" ref="base.user_root"/>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
<field name="numbercall">-1</field>
<field name="model_id" ref="product.model_product_product"/>
<field name="state">code</field>
<field name="code">model.cron_generate_brokerbin_csv()</field>
</record>
This ensures that every 24 hours, your product list is refreshed and the Brokerbin CSV is regenerated automatically.
After the cron runs successfully:
- The Brokerbin CSV is automatically generated.
- A download link appears in Odoo settings.
- The file can be uploaded to Brokerbin or shared externally.
Inventory Table
| Part Number |
Manufacturer |
Condition |
Price |
Quantity |
Description |
| X12345 |
Dell |
F/S |
CALL |
10 |
Dell OptiPlex 7090 Tower |
| X98765 |
HP |
USED |
CALL |
4 |
HP ProDesk 600 G5 SFF |
- No manual data exports.
- Automatically respects stock availability and category filters.
- Compatible with Brokerbin upload format.
- Secure, link-based CSV retrieval.
- Fully integrated into Odoo’s backend workflow.
This Brokerbin CSV automation is a practical example of how Odoo’s modular architecture can be extended to support external marketplaces efficiently. By combining configuration parameters, scheduled actions, and attachments, businesses can eliminate repetitive export tasks and maintain accurate third-party listings.
At Numla, we build lightweight, maintainable Odoo automations that scale with operational complexity. If you are looking to integrate Odoo with external marketplaces or automate inventory synchronisation, this approach serves as a proven blueprint.
Found this article useful?
Explore more development guides and solutions from our team.
Check out more posts