mirror of
https://github.com/almet/copanier.git
synced 2025-04-28 19:42:37 +02:00
Merge branch 'archive' into 'master'
Archive deliveries See merge request ybon/copanier!15
This commit is contained in:
commit
04d5fca259
11 changed files with 205 additions and 65 deletions
|
@ -177,6 +177,35 @@ async def home(request, response):
|
||||||
response.html("home.html", incoming=Delivery.incoming(), former=Delivery.former())
|
response.html("home.html", incoming=Delivery.incoming(), former=Delivery.former())
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/archives", methods=["GET"])
|
||||||
|
async def view_archives(request, response):
|
||||||
|
response.html("archive.html", {"deliveries": Delivery.all(is_archived=True)})
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/livraison/archive/{id}", methods=["GET"])
|
||||||
|
async def view_archive(request, response, id):
|
||||||
|
delivery = Delivery.load(f"archive/{id}")
|
||||||
|
response.html("delivery.html", {"delivery": delivery})
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/livraison/{id}/archiver", methods=["GET"])
|
||||||
|
@staff_only
|
||||||
|
async def archive_delivery(request, response, id):
|
||||||
|
delivery = Delivery.load(id)
|
||||||
|
delivery.archive()
|
||||||
|
response.message("La livraison a été archivée")
|
||||||
|
response.redirect = f"/livraison/{delivery.id}"
|
||||||
|
|
||||||
|
|
||||||
|
@app.route("/livraison/archive/{id}/désarchiver", methods=["GET"])
|
||||||
|
@staff_only
|
||||||
|
async def unarchive_delivery(request, response, id):
|
||||||
|
delivery = Delivery.load(f"archive/{id}")
|
||||||
|
delivery.unarchive()
|
||||||
|
response.message("La livraison a été désarchivée")
|
||||||
|
response.redirect = f"/livraison/{delivery.id}"
|
||||||
|
|
||||||
|
|
||||||
@app.route("/livraison", methods=["GET"])
|
@app.route("/livraison", methods=["GET"])
|
||||||
async def new_delivery(request, response):
|
async def new_delivery(request, response):
|
||||||
response.html("edit_delivery.html", delivery={})
|
response.html("edit_delivery.html", delivery={})
|
||||||
|
|
|
@ -151,6 +151,7 @@ class Delivery(Base):
|
||||||
CLOSED = 0
|
CLOSED = 0
|
||||||
OPEN = 1
|
OPEN = 1
|
||||||
ADJUSTMENT = 2
|
ADJUSTMENT = 2
|
||||||
|
ARCHIVED = 3
|
||||||
|
|
||||||
producer: str
|
producer: str
|
||||||
from_date: datetime_field
|
from_date: datetime_field
|
||||||
|
@ -162,11 +163,16 @@ class Delivery(Base):
|
||||||
where: str = "Marché de la Briche"
|
where: str = "Marché de la Briche"
|
||||||
products: List[Product] = field(default_factory=list)
|
products: List[Product] = field(default_factory=list)
|
||||||
orders: Dict[str, Order] = field(default_factory=dict)
|
orders: Dict[str, Order] = field(default_factory=dict)
|
||||||
id: str = field(default_factory=lambda *a, **k: uuid.uuid4().hex)
|
|
||||||
infos_url: str = ""
|
infos_url: str = ""
|
||||||
|
|
||||||
|
def __post_init__(self):
|
||||||
|
self.id = None # Not a field because we don't want to persist it.
|
||||||
|
super().__post_init__()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def status(self):
|
def status(self):
|
||||||
|
if self.is_archived:
|
||||||
|
return self.ARCHIVED
|
||||||
if self.is_open:
|
if self.is_open:
|
||||||
return self.OPEN
|
return self.OPEN
|
||||||
if self.needs_adjustment:
|
if self.needs_adjustment:
|
||||||
|
@ -197,9 +203,14 @@ class Delivery(Base):
|
||||||
def needs_adjustment(self):
|
def needs_adjustment(self):
|
||||||
return self.has_packing and any(self.product_missing(p) for p in self.products)
|
return self.has_packing and any(self.product_missing(p) for p in self.products)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_archived(self):
|
||||||
|
return self.id and self.id.startswith("archive/")
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def init_fs(cls):
|
def init_fs(cls):
|
||||||
cls.get_root().mkdir(parents=True, exist_ok=True)
|
cls.get_root().mkdir(parents=True, exist_ok=True)
|
||||||
|
cls.get_root().joinpath("archive").mkdir(exist_ok=True)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_root(cls):
|
def get_root(cls):
|
||||||
|
@ -210,12 +221,21 @@ class Delivery(Base):
|
||||||
path = cls.get_root() / f"{id}.yml"
|
path = cls.get_root() / f"{id}.yml"
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
raise DoesNotExist
|
raise DoesNotExist
|
||||||
return cls(**yaml.safe_load(path.read_text()))
|
data = yaml.safe_load(path.read_text())
|
||||||
|
# Tolerate extra fields (but we'll lose them if instance is persisted)
|
||||||
|
data = {k: v for k, v in data.items() if k in cls.__dataclass_fields__}
|
||||||
|
delivery = cls(**data)
|
||||||
|
delivery.id = id
|
||||||
|
return delivery
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def all(cls):
|
def all(cls, is_archived=False):
|
||||||
for path in cls.get_root().glob("*.yml"):
|
root = cls.get_root()
|
||||||
yield Delivery.load(path.stem)
|
if is_archived:
|
||||||
|
root = root / "archive"
|
||||||
|
for path in root.glob("*.yml"):
|
||||||
|
id_ = str(path.relative_to(cls.get_root())).replace(".yml", "")
|
||||||
|
yield Delivery.load(id_)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def incoming(cls):
|
def incoming(cls):
|
||||||
|
@ -225,10 +245,32 @@ class Delivery(Base):
|
||||||
def former(cls):
|
def former(cls):
|
||||||
return [d for d in cls.all() if not d.is_foreseen]
|
return [d for d in cls.all() if not d.is_foreseen]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def path(self):
|
||||||
|
assert self.id, "Cannot operate on unsaved deliveries"
|
||||||
|
return self.get_root() / f"{self.id}.yml"
|
||||||
|
|
||||||
def persist(self):
|
def persist(self):
|
||||||
with self.__lock__:
|
with self.__lock__:
|
||||||
path = self.get_root() / f"{self.id}.yml"
|
if not self.id:
|
||||||
path.write_text(self.dump())
|
self.id = uuid.uuid4().hex
|
||||||
|
self.path.write_text(self.dump())
|
||||||
|
|
||||||
|
def archive(self):
|
||||||
|
if self.is_archived:
|
||||||
|
raise ValueError("La livraison est déjà archivée")
|
||||||
|
current = self.path
|
||||||
|
self.id = f"archive/{self.id}"
|
||||||
|
current.rename(self.path)
|
||||||
|
|
||||||
|
def unarchive(self):
|
||||||
|
if not self.is_archived:
|
||||||
|
raise ValueError(
|
||||||
|
"Impossible de désarchiver une livraison qui n'est pas archivée"
|
||||||
|
)
|
||||||
|
current = self.path
|
||||||
|
self.id = self.path.stem
|
||||||
|
current.rename(self.path)
|
||||||
|
|
||||||
def product_wanted(self, product):
|
def product_wanted(self, product):
|
||||||
total = 0
|
total = 0
|
||||||
|
|
|
@ -208,6 +208,13 @@ input[type=submit].primary {
|
||||||
background: var(--primary-color);
|
background: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.primary:hover,
|
||||||
|
a.button.primary:hover,
|
||||||
|
input[type=submit].primary:hover {
|
||||||
|
background-color: #fff;
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
button.danger,
|
button.danger,
|
||||||
a.button.danger,
|
a.button.danger,
|
||||||
input[type=submit].danger {
|
input[type=submit].danger {
|
||||||
|
@ -215,6 +222,13 @@ input[type=submit].danger {
|
||||||
border-color: #d9534f;
|
border-color: #d9534f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button.danger:hover,
|
||||||
|
a.button.danger:hover,
|
||||||
|
input[type=submit].danger:hover {
|
||||||
|
background-color: #d9534f;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Forms */
|
/* Forms */
|
||||||
|
|
||||||
|
@ -445,7 +459,6 @@ hr {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
z-index: 100;
|
z-index: 100;
|
||||||
text-align: center;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
}
|
}
|
||||||
|
|
5
copanier/templates/archive.html
Normal file
5
copanier/templates/archive.html
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% block body %}
|
||||||
|
<h2>Livraisons archivées</h2>
|
||||||
|
{% include "includes/delivery_list.html" %}
|
||||||
|
{% endblock body %}
|
|
@ -58,6 +58,7 @@
|
||||||
</article>
|
</article>
|
||||||
<hr>
|
<hr>
|
||||||
<ul class="toolbox">
|
<ul class="toolbox">
|
||||||
|
{% if not delivery.is_archived %}
|
||||||
<li>
|
<li>
|
||||||
<a href="/livraison/{{ delivery.id }}/bon-de-commande.xlsx"><i class="icon-ribbon"></i> Bon de commande</a>
|
<a href="/livraison/{{ delivery.id }}/bon-de-commande.xlsx"><i class="icon-ribbon"></i> Bon de commande</a>
|
||||||
</li>
|
</li>
|
||||||
|
@ -67,33 +68,40 @@
|
||||||
<li>
|
<li>
|
||||||
<a href="/livraison/{{ delivery.id }}/émargement" target="_blank"><i class="icon-document"></i> Liste d'émargement</a>
|
<a href="/livraison/{{ delivery.id }}/émargement" target="_blank"><i class="icon-document"></i> Liste d'émargement</a>
|
||||||
</li>
|
</li>
|
||||||
{% if request.user and request.user.is_staff %}
|
{% if request.user and request.user.is_staff %}
|
||||||
<li>
|
<li>
|
||||||
<a href="/livraison/{{ delivery.id }}/exporter/produits"><i class="icon-layers"></i> Télécharger les produits</a>
|
<a href="/livraison/{{ delivery.id }}/exporter/produits"><i class="icon-layers"></i> Télécharger les produits</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<a href="/livraison/{{ delivery.id }}/edit"><i class="icon-adjustments"></i> Modifier la livraison</a>
|
<a href="/livraison/{{ delivery.id }}/edit"><i class="icon-adjustments"></i> Modifier la livraison</a>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{% with unique_id="import-command" %}
|
{% with unique_id="import-command" %}
|
||||||
{% include "includes/modal_import_command.html" %}
|
{% include "includes/modal_import_command.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{% with unique_id="add-command" %}
|
{% with unique_id="add-command" %}
|
||||||
{% include "includes/modal_add_command.html" %}
|
{% include "includes/modal_add_command.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
{% with unique_id="copy-emails" %}
|
{% with unique_id="copy-emails" %}
|
||||||
{% include "includes/modal_copy_emails.html" %}
|
{% include "includes/modal_copy_emails.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
</li>
|
</li>
|
||||||
{% if delivery.is_passed %}
|
{% if delivery.is_passed %}
|
||||||
<li>
|
<li>
|
||||||
<a href="/livraison/{{ delivery.id }}/solde"><i class="icon-wallet"></i> Gérer les soldes</a>
|
<a href="/livraison/{{ delivery.id }}/solde"><i class="icon-wallet"></i> Gérer les soldes</a>
|
||||||
</li>
|
</li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
{% endif %}
|
||||||
|
{% else %}
|
||||||
|
{% if request.user and request.user.is_staff %}
|
||||||
|
<li>
|
||||||
|
<a href="/livraison/{{ delivery.id }}/désarchiver" class="button danger"><i class="icon-hazardous"></i> Désarchiver</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
|
@ -45,32 +45,17 @@
|
||||||
</form>
|
</form>
|
||||||
<hr>
|
<hr>
|
||||||
{% if delivery %}
|
{% if delivery %}
|
||||||
<h3>Importer des produits</h3>
|
<ul class="toolbox">
|
||||||
<p>Formats pris en charge: xlsx, csv</p>
|
{% if delivery.status == delivery.CLOSED %}
|
||||||
<details>
|
<li>
|
||||||
<summary>Détails des colonnes</summary>
|
<a href="/livraison/{{ delivery.id }}/archiver" class="button danger"><i class="icon-hazardous"></i> Archiver</a>
|
||||||
<dl>
|
</li>
|
||||||
<dt class="mandatory">ref</dt>
|
{% endif %}
|
||||||
<dd>Référence unique du produit (permet de mettre à jour les produits en cours de commande ou d'importer des commandes individuelles).</dd>
|
<li>
|
||||||
<dt class="mandatory">name</dt>
|
{% with unique_id="import-products" %}
|
||||||
<dd>Nom du produit: mettre juste assez d'info pour distinguer les produits les uns des autres.</dd>
|
{% include "includes/modal_import_products.html" %}
|
||||||
<dt class="mandatory">price</dt>
|
{% endwith %}
|
||||||
<dd>Prix d'une unité, en euros.</dd>
|
</li>
|
||||||
<dt>unit</dt>
|
</ul>
|
||||||
<dd>Conditionnement d'une unité: 1kg, 33cl…</dd>
|
|
||||||
<dt>description</dt>
|
|
||||||
<dd>Plus de détails sur le produit.</dd>
|
|
||||||
<dt>packing</dt>
|
|
||||||
<dd>Contionnement final pour grouper les commandes, le cas échéant, en nombre d'unités.</dd>
|
|
||||||
<dt>url</dt>
|
|
||||||
<dd>Une URL éventuelle pointant sur une page présentant le produit.</dd>
|
|
||||||
<dt>img</dt>
|
|
||||||
<dd>Une URL éventuelle pointant sur une image du produit (attention, utiliser seulement des liens https).</dd>
|
|
||||||
</dl>
|
|
||||||
</details>
|
|
||||||
<form action="/livraison/{{ delivery.id }}/importer/produits" method="post" enctype="multipart/form-data">
|
|
||||||
<input type="file" name="data" required>
|
|
||||||
<input type="submit" value="Mettre à jour les produits">
|
|
||||||
</form>
|
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
|
@ -8,4 +8,5 @@
|
||||||
{% with deliveries=former %}
|
{% with deliveries=former %}
|
||||||
{% include "includes/delivery_list.html" %}
|
{% include "includes/delivery_list.html" %}
|
||||||
{% endwith %}
|
{% endwith %}
|
||||||
|
<a href="/archives">Voir les livraisons archivées</a>
|
||||||
{% endblock body %}
|
{% endblock body %}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<li><i class="icon-streetsign"></i> <strong>Lieu</strong> {{ delivery.where }}</li>
|
<li><i class="icon-streetsign"></i> <strong>Lieu</strong> {{ delivery.where }}</li>
|
||||||
<li><i class="icon-strategy"></i> <strong>Référent</strong> <a href="mailto:{{ delivery.contact }}">{{ delivery.contact }}</a></li>
|
<li><i class="icon-strategy"></i> <strong>Référent</strong> <a href="mailto:{{ delivery.contact }}">{{ delivery.contact }}</a></li>
|
||||||
<li><i class="icon-clock"></i> <strong>Date de livraison</strong> <time datetime="{{ delivery.from_date }}">{{ delivery.from_date|date }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }}</time></li>
|
<li><i class="icon-clock"></i> <strong>Date de livraison</strong> <time datetime="{{ delivery.from_date }}">{{ delivery.from_date|date }} de {{ delivery.from_date|time }} à {{ delivery.to_date|time }}</time></li>
|
||||||
<li><i class="icon-hourglass"></i> {% if delivery.status == delivery.OPEN %}<strong>Date limite de commande</strong> <time datetime="{{ delivery.order_before.date() }}">{{ delivery.order_before|date }}</time>{% elif delivery.status == delivery.ADJUSTMENT %}<strong>Ajustement en cours</strong>{% else %}<strong>Fermée</strong>{% endif %}</li>
|
<li><i class="icon-hourglass"></i> {% if delivery.status == delivery.OPEN %}<strong>Date limite de commande</strong> <time datetime="{{ delivery.order_before.date() }}">{{ delivery.order_before|date }}</time>{% elif delivery.status == delivery.ADJUSTMENT %}<strong>Ajustement en cours</strong>{% elif delivery.status == delivery.CLOSED %}<strong>Fermée</strong>{% else %}<strong>Archivée</strong>{% endif %}</li>
|
||||||
{% if delivery.instructions %}<li><i class="icon-lightbulb"></i> <strong>À savoir</strong> {{ delivery.instructions }}</li>{% endif %}
|
{% if delivery.instructions %}<li><i class="icon-lightbulb"></i> <strong>À savoir</strong> {{ delivery.instructions }}</li>{% endif %}
|
||||||
{% if delivery.infos_url %}<li><i class="icon-global"></i><strong>Plus d'infos</strong> <a href="{{ delivery.infos_url }}" title="{{ delivery.infos_url }}">{{ delivery.infos_url|truncate(20)}}</a></li>{% endif %}
|
{% if delivery.infos_url %}<li><i class="icon-global"></i><strong>Plus d'infos</strong> <a href="{{ delivery.infos_url }}" title="{{ delivery.infos_url }}">{{ delivery.infos_url|truncate(20)}}</a></li>{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
32
copanier/templates/includes/modal_import_products.html
Normal file
32
copanier/templates/includes/modal_import_products.html
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
{% extends "includes/modal.html" %}
|
||||||
|
|
||||||
|
{% block modal_label %}<i class="icon-upload"></i> Importer les produits{% endblock modal_label %}
|
||||||
|
{% block modal_body %}
|
||||||
|
<h3>Importer des produits</h3>
|
||||||
|
<p>Formats pris en charge: xlsx, csv</p>
|
||||||
|
<details>
|
||||||
|
<summary>Détails des colonnes</summary>
|
||||||
|
<dl>
|
||||||
|
<dt class="mandatory">ref</dt>
|
||||||
|
<dd>Référence unique du produit (permet de mettre à jour les produits en cours de commande ou d'importer des commandes individuelles).</dd>
|
||||||
|
<dt class="mandatory">name</dt>
|
||||||
|
<dd>Nom du produit: mettre juste assez d'info pour distinguer les produits les uns des autres.</dd>
|
||||||
|
<dt class="mandatory">price</dt>
|
||||||
|
<dd>Prix d'une unité, en euros.</dd>
|
||||||
|
<dt>unit</dt>
|
||||||
|
<dd>Conditionnement d'une unité: 1kg, 33cl…</dd>
|
||||||
|
<dt>description</dt>
|
||||||
|
<dd>Plus de détails sur le produit.</dd>
|
||||||
|
<dt>packing</dt>
|
||||||
|
<dd>Contionnement final pour grouper les commandes, le cas échéant, en nombre d'unités.</dd>
|
||||||
|
<dt>url</dt>
|
||||||
|
<dd>Une URL éventuelle pointant sur une page présentant le produit.</dd>
|
||||||
|
<dt>img</dt>
|
||||||
|
<dd>Une URL éventuelle pointant sur une image du produit (attention, utiliser seulement des liens https).</dd>
|
||||||
|
</dl>
|
||||||
|
</details>
|
||||||
|
<form action="/livraison/{{ delivery.id }}/importer/produits" method="post" enctype="multipart/form-data">
|
||||||
|
<input type="file" name="data" required>
|
||||||
|
<input type="submit" value="Mettre à jour les produits">
|
||||||
|
</form>
|
||||||
|
{% endblock modal_body %}
|
|
@ -1,4 +1,4 @@
|
||||||
{% if delivery.status != delivery.CLOSED %}
|
{% if delivery.status == delivery.OPEN or delivery.status == delivery.ADJUSTMENT %}
|
||||||
<a class="button" href="/livraison/{{ delivery.id }}/commander">
|
<a class="button" href="/livraison/{{ delivery.id }}/commander">
|
||||||
{% if delivery.status == delivery.ADJUSTMENT %}
|
{% if delivery.status == delivery.ADJUSTMENT %}
|
||||||
Ajuster ma commande
|
Ajuster ma commande
|
||||||
|
|
|
@ -20,7 +20,7 @@ def test_can_create_delivery():
|
||||||
assert delivery.producer == "Andines"
|
assert delivery.producer == "Andines"
|
||||||
assert delivery.where == "Marché de la Briche"
|
assert delivery.where == "Marché de la Briche"
|
||||||
assert delivery.from_date.year == now().year
|
assert delivery.from_date.year == now().year
|
||||||
assert delivery.id
|
assert not delivery.id
|
||||||
|
|
||||||
|
|
||||||
def test_wrong_datetime_raise_valueerror():
|
def test_wrong_datetime_raise_valueerror():
|
||||||
|
@ -106,7 +106,12 @@ def test_order_has_adjustments():
|
||||||
|
|
||||||
|
|
||||||
def test_can_persist_delivery(delivery):
|
def test_can_persist_delivery(delivery):
|
||||||
|
with pytest.raises(AssertionError):
|
||||||
|
delivery.path
|
||||||
|
assert not delivery.id
|
||||||
delivery.persist()
|
delivery.persist()
|
||||||
|
assert delivery.id
|
||||||
|
assert delivery.path.exists()
|
||||||
|
|
||||||
|
|
||||||
def test_can_load_delivery(delivery):
|
def test_can_load_delivery(delivery):
|
||||||
|
@ -138,3 +143,23 @@ def test_productorder_quantity():
|
||||||
assert choice.quantity == 5
|
assert choice.quantity == 5
|
||||||
choice = ProductOrder(wanted=3, adjustment=-1)
|
choice = ProductOrder(wanted=3, adjustment=-1)
|
||||||
assert choice.quantity == 2
|
assert choice.quantity == 2
|
||||||
|
|
||||||
|
|
||||||
|
def test_archive_delivery(delivery):
|
||||||
|
delivery.persist()
|
||||||
|
old_id = delivery.id
|
||||||
|
old_path = delivery.path
|
||||||
|
assert str(old_path).endswith(f"delivery/{delivery.id}.yml")
|
||||||
|
assert old_path.exists()
|
||||||
|
delivery.archive()
|
||||||
|
assert delivery.is_archived
|
||||||
|
assert delivery.id.startswith("archive/")
|
||||||
|
new_path = delivery.path
|
||||||
|
assert str(new_path).endswith(f"delivery/archive/{old_id}.yml")
|
||||||
|
assert not old_path.exists()
|
||||||
|
assert new_path.exists()
|
||||||
|
delivery.unarchive()
|
||||||
|
assert not delivery.id.startswith("archive/")
|
||||||
|
assert old_path.exists()
|
||||||
|
assert not new_path.exists()
|
||||||
|
assert not delivery.is_archived
|
||||||
|
|
Loading…
Reference in a new issue