Skip to content

demonewgenij-maker/onec-price-updater

Repository files navigation

onec-price-updater

CI

A clean, testable Python toolkit for updating nomenclature prices in 1C / 1Enterprise from supplier CSV price-lists — with dry-run safety, retry logic, and a human-readable diff report.

Design Decisions

Decision Rationale
Env-only config No secrets in code or config files; .env.example ships as the only template
Dry-run by default DRY_RUN=true out of the box; the operator must explicitly opt-in to writes
Retry on transient 404/5xx 1C HTTP-services can return transient 404 during reload; exponential back-off with configurable delay
Pure, testable parser/matcher Parser uses stdlib csv; matcher uses Jaccard similarity — no network, no 1C needed for tests
Decimal prices decimal.Decimal throughout to avoid float rounding errors in financial data
Ambiguity surfaced, not resolved When multiple 1C entries match equally well, the item is flagged for manual review rather than silently picking one

Pipeline

 Supplier price-list (CSV / XLSX)
          |
          v
    [ parser.py ]          parse_pricelist()
          |                    PriceItem list
          v
    [ matcher.py ]         match_items(items, nomenclature)
          |                    MatchResult list
          v
    [ diff_report.py ]     build_diff(old_prices, matches)
          |                    PriceChange list
          v
    [ price_writer.py ]    write_prices(client, changes, dry_run=True)
          |
          v
      1C via HTTP          OneCClient.write_price()

Project Structure

onec-price-updater/
├── README.md
├── LICENSE
├── .gitignore
├── .env.example
├── requirements.txt
├── pyproject.toml
├── sample_data/
│   └── pricelist_example.csv
├── src/pricebot/
│   ├── __init__.py
│   ├── config.py          env-driven settings + domain constants
│   ├── models.py          PriceItem, NomenclatureRef, MatchResult, PriceChange
│   ├── parser.py          CSV parser + mtime-based price-list date
│   ├── matcher.py         Jaccard-similarity matcher with ambiguity detection
│   ├── onec_client.py     HTTP client for 1C (fetch nomenclature / prices / write)
│   ├── price_writer.py    Applies or dry-runs the price changes
│   ├── diff_report.py     Builds and renders the human-readable diff
│   └── retry.py           Exponential back-off decorator for transient errors
└── tests/
    ├── test_parser.py
    ├── test_matcher.py
    ├── test_diff_report.py
    └── test_retry.py

Quick Start

# 1. Create and activate a virtual environment
python -m venv .venv
# Windows:
.venv\Scripts\activate
# macOS / Linux:
source .venv/bin/activate

# 2. Install dependencies
pip install -r requirements.txt

# 3. Configure
cp .env.example .env
# Edit .env: set ONEC_BASE_URL and ONEC_TOKEN

# 4. Run a dry-run demo on the sample data
#    (DRY_RUN=true by default — no data is written)
python - <<'EOF'
from pricebot.parser import parse_pricelist
from pricebot.diff_report import render_report, build_diff
from pricebot.matcher import match_items
from decimal import Decimal

items = parse_pricelist("sample_data/pricelist_example.csv")
print(f"Parsed {len(items)} items from price-list")

# Without a real 1C connection, pass an empty nomenclature list
results = match_items(items, [])
changes = build_diff({}, results)
print(render_report(changes, results))
EOF

# 5. Run the test suite (no network required)
pytest

Note

This is a sanitised, from-scratch reference implementation. All supplier names ("Acme Roofing"), product series ("Classic", "Premium", "Standard"), and article numbers are entirely fictional and do not represent any real company or product.

License

MIT — see LICENSE.

About

Python toolkit to update 1C/1Enterprise nomenclature prices from supplier price-lists: parser, matcher, diff report, retrying HTTP client. Dry-run by default, fully tested.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages