Skip to content

Commit 20a0818

Browse files
committed
new test that we can also load existing allocations
1 parent fdafb60 commit 20a0818

2 files changed

Lines changed: 106 additions & 29 deletions

File tree

src/bin/allocate-from-csv

Lines changed: 63 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,82 @@
11
#!/usr/bin/env python
2+
from __future__ import annotations
3+
from typing import Dict
24
import csv
35
import sys
46
from datetime import datetime
57
from pathlib import Path
68

79
from allocation.domain import model
10+
from allocation.service_layer import services, unit_of_work
11+
from allocation.adapters import repository
812

913

10-
def load_batches(batches_path):
11-
batches = []
12-
with batches_path.open() as inf:
13-
reader = csv.DictReader(inf)
14-
for row in reader:
15-
if row["eta"]:
16-
eta = datetime.strptime(row["eta"], "%Y-%m-%d").date()
17-
else:
18-
eta = None
19-
batches.append(
20-
model.Batch(
21-
ref=row["ref"], sku=row["sku"], qty=int(row["qty"]), eta=eta
22-
)
23-
)
24-
return batches
14+
class CsvRepository(repository.AbstractRepository):
15+
def __init__(self, folder):
16+
self._batches_path = Path(folder) / "batches.csv"
17+
self._allocations_path = Path(folder) / "allocations.csv"
18+
self._batches = {} # type: Dict[str, model.Batch]
19+
self._load()
2520

21+
def get(self, reference):
22+
return self._batches.get(reference)
23+
24+
def add(self, batch):
25+
self._batches[batch.reference] = batch
26+
27+
def _load(self):
28+
with self._batches_path.open() as f:
29+
reader = csv.DictReader(f)
30+
for row in reader:
31+
ref, sku = row["ref"], row["sku"]
32+
qty = int(row["qty"])
33+
if row["eta"]:
34+
eta = datetime.strptime(row["eta"], "%Y-%m-%d").date()
35+
else:
36+
eta = None
37+
self._batches[ref] = model.Batch(ref=ref, sku=sku, qty=qty, eta=eta)
38+
if self._allocations_path.exists() is False:
39+
return
40+
with self._allocations_path.open() as f:
41+
reader = csv.DictReader(f)
42+
for row in reader:
43+
batchref, orderid, sku = row["batchref"], row["orderid"], row["sku"]
44+
qty = int(row["qty"])
45+
line = model.OrderLine(orderid, sku, qty)
46+
batch = self._batches[batchref]
47+
batch._allocations.add(line)
48+
49+
def list(self):
50+
return list(self._batches.values())
2651

27-
def main(folder):
28-
batches_path = Path(folder) / "batches.csv"
29-
orders_path = Path(folder) / "orders.csv"
30-
allocations_path = Path(folder) / "allocations.csv"
3152

32-
batches = load_batches(batches_path)
53+
class CsvUnitOfWork(unit_of_work.AbstractUnitOfWork):
54+
def __init__(self, folder):
55+
self.batches = CsvRepository(folder)
3356

34-
with orders_path.open() as inf, allocations_path.open("w") as outf:
35-
reader = csv.DictReader(inf)
36-
writer = csv.writer(outf)
37-
writer.writerow(["orderid", "sku", "batchref"])
57+
def commit(self):
58+
with self.batches._allocations_path.open("w") as f:
59+
writer = csv.writer(f)
60+
writer.writerow(["orderid", "sku", "qty", "batchref"])
61+
for batch in self.batches.list():
62+
for line in batch._allocations:
63+
writer.writerow(
64+
[line.orderid, line.sku, line.qty, batch.reference]
65+
)
66+
67+
def rollback(self):
68+
pass
69+
70+
71+
def main(folder):
72+
orders_path = Path(folder) / "orders.csv"
73+
uow = CsvUnitOfWork(folder)
74+
with orders_path.open() as f:
75+
reader = csv.DictReader(f)
3876
for row in reader:
3977
orderid, sku = row["orderid"], row["sku"]
4078
qty = int(row["qty"])
41-
line = model.OrderLine(orderid, sku, qty)
42-
batchref = model.allocate(line, batches)
43-
writer.writerow([line.orderid, line.sku, batchref])
79+
services.allocate(orderid, sku, qty, uow)
4480

4581

4682
if __name__ == "__main__":

tests/e2e/test_csv.py

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
import csv
2-
import subprocess
32
import uuid
3+
from importlib.util import spec_from_loader, module_from_spec
4+
from importlib.machinery import SourceFileLoader
5+
from pathlib import Path
46

57

68
def random_ref(prefix):
79
return prefix + "-" + uuid.uuid4().hex[:10]
810

911

12+
def run_cli_script(folder):
13+
"""a bit of python import hackery to load the script and run its main()"""
14+
path = Path(__file__).parent / "../../src/bin/allocate-from-csv"
15+
spec = spec_from_loader("script", SourceFileLoader("script", str(path)))
16+
script = module_from_spec(spec)
17+
spec.loader.exec_module(script)
18+
script.main(folder)
19+
20+
1021
def test_cli_app_reads_csvs_with_batches_and_orders_and_outputs_allocations(make_csv):
1122
sku1, sku2 = random_ref("s1"), random_ref("s2")
1223
batch1, batch2, batch3 = random_ref("b1"), random_ref("b2"), random_ref("b3")
@@ -23,7 +34,7 @@ def test_cli_app_reads_csvs_with_batches_and_orders_and_outputs_allocations(make
2334
[order_ref, sku2, 12],
2435
])
2536

26-
subprocess.run(["allocate-from-csv", orders_csv.parent])
37+
run_cli_script(orders_csv.parent)
2738

2839
expected_output_csv = orders_csv.parent / "allocations.csv"
2940
with open(expected_output_csv) as f:
@@ -33,3 +44,33 @@ def test_cli_app_reads_csvs_with_batches_and_orders_and_outputs_allocations(make
3344
[order_ref, sku1, "3", batch1],
3445
[order_ref, sku2, "12", batch2],
3546
]
47+
48+
49+
def test_cli_app_also_reads_existing_allocations_and_can_append_to_them(make_csv):
50+
sku = random_ref("s")
51+
batch1, batch2 = random_ref("b1"), random_ref("b2")
52+
old_order, new_order = random_ref("o1"), random_ref("o2")
53+
make_csv("batches.csv", [
54+
["ref", "sku", "qty", "eta"],
55+
[batch1, sku, 10, "2011-01-01"],
56+
[batch2, sku, 10, "2011-01-02"],
57+
])
58+
make_csv("allocations.csv", [
59+
["orderid", "sku", "qty", "batchref"],
60+
[old_order, sku, 10, batch1],
61+
])
62+
orders_csv = make_csv("orders.csv", [
63+
["orderid", "sku", "qty"],
64+
[new_order, sku, 7],
65+
])
66+
67+
run_cli_script(orders_csv.parent)
68+
69+
expected_output_csv = orders_csv.parent / "allocations.csv"
70+
with open(expected_output_csv) as f:
71+
rows = list(csv.reader(f))
72+
assert rows == [
73+
["orderid", "sku", "qty", "batchref"],
74+
[old_order, sku, "10", batch1],
75+
[new_order, sku, "7", batch2],
76+
]

0 commit comments

Comments
 (0)