logisticspy 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- logisticspy-0.1.0/LICENSE +21 -0
- logisticspy-0.1.0/PKG-INFO +220 -0
- logisticspy-0.1.0/README.md +198 -0
- logisticspy-0.1.0/logisticspy/__init__.py +43 -0
- logisticspy-0.1.0/logisticspy/weight/__init__.py +28 -0
- logisticspy-0.1.0/logisticspy/weight/chargeable_weight.py +291 -0
- logisticspy-0.1.0/logisticspy/weight/divisors.py +72 -0
- logisticspy-0.1.0/logisticspy.egg-info/PKG-INFO +220 -0
- logisticspy-0.1.0/logisticspy.egg-info/SOURCES.txt +13 -0
- logisticspy-0.1.0/logisticspy.egg-info/dependency_links.txt +1 -0
- logisticspy-0.1.0/logisticspy.egg-info/requires.txt +3 -0
- logisticspy-0.1.0/logisticspy.egg-info/top_level.txt +1 -0
- logisticspy-0.1.0/pyproject.toml +33 -0
- logisticspy-0.1.0/setup.cfg +4 -0
- logisticspy-0.1.0/tests/test_chargeable_weight.py +301 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 krishnanz550i-cmyk
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: logisticspy
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: A Python toolkit for logistics and supply chain calculations
|
|
5
|
+
Author: krishnanz550i-cmyk
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/krishnanz550i-cmyk/logisticspy
|
|
8
|
+
Project-URL: Issues, https://github.com/krishnanz550i-cmyk/logisticspy/issues
|
|
9
|
+
Keywords: logistics,supply chain,freight,chargeable weight
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Topic :: Office/Business
|
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
|
16
|
+
Requires-Python: >=3.8
|
|
17
|
+
Description-Content-Type: text/markdown
|
|
18
|
+
License-File: LICENSE
|
|
19
|
+
Provides-Extra: dev
|
|
20
|
+
Requires-Dist: pytest; extra == "dev"
|
|
21
|
+
Dynamic: license-file
|
|
22
|
+
|
|
23
|
+
# logisticspy
|
|
24
|
+
|
|
25
|
+
A Python toolkit for logistics and supply chain calculations.
|
|
26
|
+
|
|
27
|
+
`logisticspy` is a growing collection of clean, well-tested tools for
|
|
28
|
+
common logistics and supply chain problems. The first module,
|
|
29
|
+
**`logisticspy.weight`**, calculates volumetric (dimensional) weight and
|
|
30
|
+
chargeable weight for air, courier, sea, road, and rail freight shipments.
|
|
31
|
+
More tools (volume, freight, inventory, and others) will be added over
|
|
32
|
+
time.
|
|
33
|
+
|
|
34
|
+
## Install
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pip install logisticspy
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick start
|
|
41
|
+
|
|
42
|
+
You can use the chargeable weight tools either via the top-level package
|
|
43
|
+
or via the `weight` module:
|
|
44
|
+
|
|
45
|
+
```python
|
|
46
|
+
# Option 1: top-level import
|
|
47
|
+
import logisticspy
|
|
48
|
+
|
|
49
|
+
result = logisticspy.calculate(
|
|
50
|
+
length=60, width=40, height=40, unit="cm",
|
|
51
|
+
actual_weight=18, weight_unit="kg",
|
|
52
|
+
mode="air",
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# Option 2: import the weight module
|
|
56
|
+
from logisticspy.weight import chargeable_weight
|
|
57
|
+
|
|
58
|
+
result = chargeable_weight.calculate(
|
|
59
|
+
length=60, width=40, height=40, unit="cm",
|
|
60
|
+
actual_weight=18, weight_unit="kg",
|
|
61
|
+
mode="air",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
print(result.volumetric_weight_kg) # 19.2
|
|
65
|
+
print(result.chargeable_weight_kg) # 19.2
|
|
66
|
+
print(result.basis) # "volumetric"
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## The `weight` module: chargeable weight
|
|
70
|
+
|
|
71
|
+
Carriers bill shipments based on whichever is greater: the **actual
|
|
72
|
+
weight** or the **volumetric weight** (calculated from package
|
|
73
|
+
dimensions). This module implements that calculation cleanly, with
|
|
74
|
+
support for multiple units, transport modes, named divisor presets, and
|
|
75
|
+
multi-package consignments.
|
|
76
|
+
|
|
77
|
+
### Supported modes and default divisors
|
|
78
|
+
|
|
79
|
+
| Mode | Default divisor (cm³/kg) |
|
|
80
|
+
|-----------|---------------------------|
|
|
81
|
+
| `air` | 6000 |
|
|
82
|
+
| `courier` | 5000 |
|
|
83
|
+
| `road` | 3000 |
|
|
84
|
+
| `rail` | 3000 |
|
|
85
|
+
| `sea` | N/A (uses CBM × 1000, see below) |
|
|
86
|
+
|
|
87
|
+
These are sensible starting defaults based on common conventions seen
|
|
88
|
+
across the freight and parcel industry. They are **not** tied to any
|
|
89
|
+
specific carrier - always confirm the applicable divisor with your own
|
|
90
|
+
carrier or contract for billing-critical calculations.
|
|
91
|
+
|
|
92
|
+
### Divisor presets
|
|
93
|
+
|
|
94
|
+
Two divisor values - 5000 and 6000 - are both widely used across the
|
|
95
|
+
industry, often for different services, regions, or contracts (sometimes
|
|
96
|
+
even by the same carrier depending on the product). Rather than guessing
|
|
97
|
+
which one applies to your situation, you can refer to them by generic
|
|
98
|
+
preset labels and swap between them easily:
|
|
99
|
+
|
|
100
|
+
| Preset | Divisor |
|
|
101
|
+
|--------|---------|
|
|
102
|
+
| `"a"` | 5000 |
|
|
103
|
+
| `"b"` | 6000 |
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
import logisticspy
|
|
107
|
+
|
|
108
|
+
# Same package, two different divisor conventions
|
|
109
|
+
pkg = dict(length=60, width=40, height=40, actual_weight=10, mode="air")
|
|
110
|
+
|
|
111
|
+
result_a = logisticspy.calculate(**pkg, divisor_preset="a") # divisor 5000
|
|
112
|
+
result_b = logisticspy.calculate(**pkg, divisor_preset="b") # divisor 6000
|
|
113
|
+
|
|
114
|
+
print(result_a.volumetric_weight_kg) # 19.2
|
|
115
|
+
print(result_b.volumetric_weight_kg) # 16.0
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This makes it easy to compare "what would this shipment cost under each
|
|
119
|
+
convention" without hardcoding either value, and to plug in your own
|
|
120
|
+
carrier's documented divisor (whether that happens to be 5000, 6000, or
|
|
121
|
+
something else entirely) via `divisor_preset` or a raw `divisor=` value.
|
|
122
|
+
|
|
123
|
+
You can also pass an explicit divisor directly, which overrides any preset:
|
|
124
|
+
|
|
125
|
+
```python
|
|
126
|
+
result = logisticspy.calculate(**pkg, divisor=4500)
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Units
|
|
130
|
+
|
|
131
|
+
#### Input units
|
|
132
|
+
|
|
133
|
+
Dimensions accept `cm`, `m`, `mm`, `in`, `ft` (default `cm`).
|
|
134
|
+
Weights accept `kg`, `g`, `lb`, `oz` (default `kg`).
|
|
135
|
+
|
|
136
|
+
```python
|
|
137
|
+
result = logisticspy.calculate(
|
|
138
|
+
length=20, width=15, height=10, unit="in",
|
|
139
|
+
actual_weight=5, weight_unit="lb",
|
|
140
|
+
mode="courier",
|
|
141
|
+
)
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
#### Output units (always normalized)
|
|
145
|
+
|
|
146
|
+
Regardless of the input units you choose, **all results are returned in
|
|
147
|
+
a single fixed unit system**:
|
|
148
|
+
|
|
149
|
+
| Field | Unit |
|
|
150
|
+
|-------|------|
|
|
151
|
+
| `actual_weight_kg`, `volumetric_weight_kg`, `chargeable_weight_kg` | kilograms (kg) |
|
|
152
|
+
| `volume_m3` | cubic meters (m³) |
|
|
153
|
+
|
|
154
|
+
The input units (`unit`, `weight_unit`) are only used to *interpret* the
|
|
155
|
+
numbers you pass in - they are converted to centimeters and kilograms
|
|
156
|
+
internally before any calculation happens. The output is never expressed
|
|
157
|
+
back in the input units.
|
|
158
|
+
|
|
159
|
+
If you need the result in a different unit (e.g. pounds), convert the
|
|
160
|
+
returned kg value yourself - the library does not provide unit conversion
|
|
161
|
+
on outputs.
|
|
162
|
+
|
|
163
|
+
### Sea freight (CBM)
|
|
164
|
+
|
|
165
|
+
Sea freight chargeable weight is derived from volume in cubic meters
|
|
166
|
+
(CBM), using the common 1 CBM ≈ 1000 kg convention:
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
result = logisticspy.calculate(
|
|
170
|
+
length=1, width=1, height=1, unit="m",
|
|
171
|
+
actual_weight=500, mode="sea",
|
|
172
|
+
)
|
|
173
|
+
print(result.volumetric_weight_kg) # 1000.0
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Divisor presets are ignored for sea mode, since it uses a CBM-based
|
|
177
|
+
calculation rather than a divisor.
|
|
178
|
+
|
|
179
|
+
### Multi-package consignments
|
|
180
|
+
|
|
181
|
+
```python
|
|
182
|
+
import logisticspy
|
|
183
|
+
|
|
184
|
+
packages = [
|
|
185
|
+
{"length": 50, "width": 40, "height": 40, "actual_weight": 10},
|
|
186
|
+
{"length": 60, "width": 40, "height": 40, "actual_weight": 25, "quantity": 2},
|
|
187
|
+
]
|
|
188
|
+
|
|
189
|
+
result = logisticspy.calculate_consignment(packages, mode="air")
|
|
190
|
+
|
|
191
|
+
print(result.total_actual_weight_kg)
|
|
192
|
+
print(result.total_volumetric_weight_kg)
|
|
193
|
+
print(result.total_chargeable_weight_kg)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
By default, totals are compared (`sum(actual)` vs `sum(volumetric)`).
|
|
197
|
+
Some couriers calculate chargeable weight per package and sum those - use
|
|
198
|
+
`per_piece=True` for that behavior:
|
|
199
|
+
|
|
200
|
+
```python
|
|
201
|
+
result = logisticspy.calculate_consignment(packages, mode="air", per_piece=True)
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
## Roadmap
|
|
205
|
+
|
|
206
|
+
`logisticspy` is designed to grow into a broader logistics toolkit.
|
|
207
|
+
`chargeable_weight` is the first module; additional tools (e.g. volume,
|
|
208
|
+
freight, and inventory calculations) will be added over time.
|
|
209
|
+
|
|
210
|
+
## Disclaimer
|
|
211
|
+
|
|
212
|
+
This library implements widely-used industry conventions for
|
|
213
|
+
illustrative and estimation purposes. Divisors and CBM ratios vary by
|
|
214
|
+
carrier, service level, region, and contract terms. Always confirm exact
|
|
215
|
+
billing methodology with your carrier or freight forwarder for
|
|
216
|
+
invoicing-critical calculations.
|
|
217
|
+
|
|
218
|
+
## License
|
|
219
|
+
|
|
220
|
+
MIT
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
# logisticspy
|
|
2
|
+
|
|
3
|
+
A Python toolkit for logistics and supply chain calculations.
|
|
4
|
+
|
|
5
|
+
`logisticspy` is a growing collection of clean, well-tested tools for
|
|
6
|
+
common logistics and supply chain problems. The first module,
|
|
7
|
+
**`logisticspy.weight`**, calculates volumetric (dimensional) weight and
|
|
8
|
+
chargeable weight for air, courier, sea, road, and rail freight shipments.
|
|
9
|
+
More tools (volume, freight, inventory, and others) will be added over
|
|
10
|
+
time.
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
pip install logisticspy
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Quick start
|
|
19
|
+
|
|
20
|
+
You can use the chargeable weight tools either via the top-level package
|
|
21
|
+
or via the `weight` module:
|
|
22
|
+
|
|
23
|
+
```python
|
|
24
|
+
# Option 1: top-level import
|
|
25
|
+
import logisticspy
|
|
26
|
+
|
|
27
|
+
result = logisticspy.calculate(
|
|
28
|
+
length=60, width=40, height=40, unit="cm",
|
|
29
|
+
actual_weight=18, weight_unit="kg",
|
|
30
|
+
mode="air",
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# Option 2: import the weight module
|
|
34
|
+
from logisticspy.weight import chargeable_weight
|
|
35
|
+
|
|
36
|
+
result = chargeable_weight.calculate(
|
|
37
|
+
length=60, width=40, height=40, unit="cm",
|
|
38
|
+
actual_weight=18, weight_unit="kg",
|
|
39
|
+
mode="air",
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
print(result.volumetric_weight_kg) # 19.2
|
|
43
|
+
print(result.chargeable_weight_kg) # 19.2
|
|
44
|
+
print(result.basis) # "volumetric"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## The `weight` module: chargeable weight
|
|
48
|
+
|
|
49
|
+
Carriers bill shipments based on whichever is greater: the **actual
|
|
50
|
+
weight** or the **volumetric weight** (calculated from package
|
|
51
|
+
dimensions). This module implements that calculation cleanly, with
|
|
52
|
+
support for multiple units, transport modes, named divisor presets, and
|
|
53
|
+
multi-package consignments.
|
|
54
|
+
|
|
55
|
+
### Supported modes and default divisors
|
|
56
|
+
|
|
57
|
+
| Mode | Default divisor (cm³/kg) |
|
|
58
|
+
|-----------|---------------------------|
|
|
59
|
+
| `air` | 6000 |
|
|
60
|
+
| `courier` | 5000 |
|
|
61
|
+
| `road` | 3000 |
|
|
62
|
+
| `rail` | 3000 |
|
|
63
|
+
| `sea` | N/A (uses CBM × 1000, see below) |
|
|
64
|
+
|
|
65
|
+
These are sensible starting defaults based on common conventions seen
|
|
66
|
+
across the freight and parcel industry. They are **not** tied to any
|
|
67
|
+
specific carrier - always confirm the applicable divisor with your own
|
|
68
|
+
carrier or contract for billing-critical calculations.
|
|
69
|
+
|
|
70
|
+
### Divisor presets
|
|
71
|
+
|
|
72
|
+
Two divisor values - 5000 and 6000 - are both widely used across the
|
|
73
|
+
industry, often for different services, regions, or contracts (sometimes
|
|
74
|
+
even by the same carrier depending on the product). Rather than guessing
|
|
75
|
+
which one applies to your situation, you can refer to them by generic
|
|
76
|
+
preset labels and swap between them easily:
|
|
77
|
+
|
|
78
|
+
| Preset | Divisor |
|
|
79
|
+
|--------|---------|
|
|
80
|
+
| `"a"` | 5000 |
|
|
81
|
+
| `"b"` | 6000 |
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
import logisticspy
|
|
85
|
+
|
|
86
|
+
# Same package, two different divisor conventions
|
|
87
|
+
pkg = dict(length=60, width=40, height=40, actual_weight=10, mode="air")
|
|
88
|
+
|
|
89
|
+
result_a = logisticspy.calculate(**pkg, divisor_preset="a") # divisor 5000
|
|
90
|
+
result_b = logisticspy.calculate(**pkg, divisor_preset="b") # divisor 6000
|
|
91
|
+
|
|
92
|
+
print(result_a.volumetric_weight_kg) # 19.2
|
|
93
|
+
print(result_b.volumetric_weight_kg) # 16.0
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
This makes it easy to compare "what would this shipment cost under each
|
|
97
|
+
convention" without hardcoding either value, and to plug in your own
|
|
98
|
+
carrier's documented divisor (whether that happens to be 5000, 6000, or
|
|
99
|
+
something else entirely) via `divisor_preset` or a raw `divisor=` value.
|
|
100
|
+
|
|
101
|
+
You can also pass an explicit divisor directly, which overrides any preset:
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
result = logisticspy.calculate(**pkg, divisor=4500)
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### Units
|
|
108
|
+
|
|
109
|
+
#### Input units
|
|
110
|
+
|
|
111
|
+
Dimensions accept `cm`, `m`, `mm`, `in`, `ft` (default `cm`).
|
|
112
|
+
Weights accept `kg`, `g`, `lb`, `oz` (default `kg`).
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
result = logisticspy.calculate(
|
|
116
|
+
length=20, width=15, height=10, unit="in",
|
|
117
|
+
actual_weight=5, weight_unit="lb",
|
|
118
|
+
mode="courier",
|
|
119
|
+
)
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
#### Output units (always normalized)
|
|
123
|
+
|
|
124
|
+
Regardless of the input units you choose, **all results are returned in
|
|
125
|
+
a single fixed unit system**:
|
|
126
|
+
|
|
127
|
+
| Field | Unit |
|
|
128
|
+
|-------|------|
|
|
129
|
+
| `actual_weight_kg`, `volumetric_weight_kg`, `chargeable_weight_kg` | kilograms (kg) |
|
|
130
|
+
| `volume_m3` | cubic meters (m³) |
|
|
131
|
+
|
|
132
|
+
The input units (`unit`, `weight_unit`) are only used to *interpret* the
|
|
133
|
+
numbers you pass in - they are converted to centimeters and kilograms
|
|
134
|
+
internally before any calculation happens. The output is never expressed
|
|
135
|
+
back in the input units.
|
|
136
|
+
|
|
137
|
+
If you need the result in a different unit (e.g. pounds), convert the
|
|
138
|
+
returned kg value yourself - the library does not provide unit conversion
|
|
139
|
+
on outputs.
|
|
140
|
+
|
|
141
|
+
### Sea freight (CBM)
|
|
142
|
+
|
|
143
|
+
Sea freight chargeable weight is derived from volume in cubic meters
|
|
144
|
+
(CBM), using the common 1 CBM ≈ 1000 kg convention:
|
|
145
|
+
|
|
146
|
+
```python
|
|
147
|
+
result = logisticspy.calculate(
|
|
148
|
+
length=1, width=1, height=1, unit="m",
|
|
149
|
+
actual_weight=500, mode="sea",
|
|
150
|
+
)
|
|
151
|
+
print(result.volumetric_weight_kg) # 1000.0
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
Divisor presets are ignored for sea mode, since it uses a CBM-based
|
|
155
|
+
calculation rather than a divisor.
|
|
156
|
+
|
|
157
|
+
### Multi-package consignments
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
import logisticspy
|
|
161
|
+
|
|
162
|
+
packages = [
|
|
163
|
+
{"length": 50, "width": 40, "height": 40, "actual_weight": 10},
|
|
164
|
+
{"length": 60, "width": 40, "height": 40, "actual_weight": 25, "quantity": 2},
|
|
165
|
+
]
|
|
166
|
+
|
|
167
|
+
result = logisticspy.calculate_consignment(packages, mode="air")
|
|
168
|
+
|
|
169
|
+
print(result.total_actual_weight_kg)
|
|
170
|
+
print(result.total_volumetric_weight_kg)
|
|
171
|
+
print(result.total_chargeable_weight_kg)
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
By default, totals are compared (`sum(actual)` vs `sum(volumetric)`).
|
|
175
|
+
Some couriers calculate chargeable weight per package and sum those - use
|
|
176
|
+
`per_piece=True` for that behavior:
|
|
177
|
+
|
|
178
|
+
```python
|
|
179
|
+
result = logisticspy.calculate_consignment(packages, mode="air", per_piece=True)
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Roadmap
|
|
183
|
+
|
|
184
|
+
`logisticspy` is designed to grow into a broader logistics toolkit.
|
|
185
|
+
`chargeable_weight` is the first module; additional tools (e.g. volume,
|
|
186
|
+
freight, and inventory calculations) will be added over time.
|
|
187
|
+
|
|
188
|
+
## Disclaimer
|
|
189
|
+
|
|
190
|
+
This library implements widely-used industry conventions for
|
|
191
|
+
illustrative and estimation purposes. Divisors and CBM ratios vary by
|
|
192
|
+
carrier, service level, region, and contract terms. Always confirm exact
|
|
193
|
+
billing methodology with your carrier or freight forwarder for
|
|
194
|
+
invoicing-critical calculations.
|
|
195
|
+
|
|
196
|
+
## License
|
|
197
|
+
|
|
198
|
+
MIT
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""
|
|
2
|
+
logisticspy: A Python toolkit for logistics and supply chain calculations.
|
|
3
|
+
|
|
4
|
+
The first module, ``logisticspy.weight``, calculates volumetric (dimensional)
|
|
5
|
+
and chargeable weight for air, courier, sea, road, and rail freight shipments.
|
|
6
|
+
More tools will be added over time.
|
|
7
|
+
|
|
8
|
+
Top-level convenience imports let you do either of:
|
|
9
|
+
|
|
10
|
+
import logisticspy
|
|
11
|
+
logisticspy.calculate(...)
|
|
12
|
+
|
|
13
|
+
from logisticspy.weight import chargeable_weight
|
|
14
|
+
chargeable_weight.calculate(...)
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from .weight import (
|
|
18
|
+
calculate,
|
|
19
|
+
calculate_consignment,
|
|
20
|
+
WeightResult,
|
|
21
|
+
ConsolidatedResult,
|
|
22
|
+
Mode,
|
|
23
|
+
DEFAULT_DIVISORS,
|
|
24
|
+
DIVISOR_PRESETS,
|
|
25
|
+
UnsupportedUnitError,
|
|
26
|
+
UnsupportedModeError,
|
|
27
|
+
UnsupportedPresetError,
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
__version__ = "0.1.0"
|
|
31
|
+
|
|
32
|
+
__all__ = [
|
|
33
|
+
"calculate",
|
|
34
|
+
"calculate_consignment",
|
|
35
|
+
"WeightResult",
|
|
36
|
+
"ConsolidatedResult",
|
|
37
|
+
"Mode",
|
|
38
|
+
"DEFAULT_DIVISORS",
|
|
39
|
+
"DIVISOR_PRESETS",
|
|
40
|
+
"UnsupportedUnitError",
|
|
41
|
+
"UnsupportedModeError",
|
|
42
|
+
"UnsupportedPresetError",
|
|
43
|
+
]
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
logisticspy.weight: Calculate volumetric (dimensional) and chargeable weight
|
|
3
|
+
for air, courier, sea, road, and rail freight shipments.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
from .chargeable_weight import (
|
|
7
|
+
calculate,
|
|
8
|
+
calculate_consignment,
|
|
9
|
+
WeightResult,
|
|
10
|
+
ConsolidatedResult,
|
|
11
|
+
UnsupportedUnitError,
|
|
12
|
+
UnsupportedModeError,
|
|
13
|
+
UnsupportedPresetError,
|
|
14
|
+
)
|
|
15
|
+
from .divisors import Mode, DEFAULT_DIVISORS, DIVISOR_PRESETS
|
|
16
|
+
|
|
17
|
+
__all__ = [
|
|
18
|
+
"calculate",
|
|
19
|
+
"calculate_consignment",
|
|
20
|
+
"WeightResult",
|
|
21
|
+
"ConsolidatedResult",
|
|
22
|
+
"Mode",
|
|
23
|
+
"DEFAULT_DIVISORS",
|
|
24
|
+
"DIVISOR_PRESETS",
|
|
25
|
+
"UnsupportedUnitError",
|
|
26
|
+
"UnsupportedModeError",
|
|
27
|
+
"UnsupportedPresetError",
|
|
28
|
+
]
|