Parcourir la source

Date invoices, and their due dates, from the latest edit

An edit re-sends an invoice, so Created and Due now count from the newest
version (modified) rather than the first one.

On FlatFile, modified always came back as the oldest date.  read() runs
filter() on each file and get() runs it again, so the second pass of
_dedup_versions() saw one version whose created the first pass had already
rewritten, and copied that into modified.  That is the fault the old XXX
comment described.  It now keeps a modified that is already there, which only
a previous pass can have set: validate() drops it on save.

t/Trog-Log-Syslog.t bails out on master as well, and is not touched here.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
George Baugh il y a 1 semaine
Parent
commit
ced9e8db97

+ 3 - 2
lib/Trog/DataModule.pm

@@ -295,8 +295,9 @@ sub _dedup_versions ( $version = -1, @posts ) {
         $posts_deduped{$id}{version_max} = $version_max;
 
         # Show orig creation date, and original author.
-        # XXX this doesn't show the mtime correctly for whatever reason, so I'm omitting it from the interface
-        $posts_deduped{$id}{modified} = $ofid[0]{created};
+        # A modified already present is from an earlier pass, which FlatFile makes
+        # in read() before get() filters again; validate() never lets one be stored.
+        $posts_deduped{$id}{modified} = $ofid[0]{modified} // $ofid[0]{created};
         $posts_deduped{$id}{created}  = $ofid[-1]{created};
         $posts_deduped{$id}{author}   = $ofid[-1]{author};
     }

+ 22 - 3
t/Trog-Routes-HTML-series-lifecycle.t

@@ -40,6 +40,14 @@ our $MODEL;
 # In BEGIN because the sandbox is built in one, before file scope runs.
 BEGIN { $MODEL = $ENV{TCMS_TEST_DATA_MODEL} || 'FlatFile' }
 
+# What time() answers in every module required below, so two saves can land on
+# different days; undef is the real clock.
+our $NOW;
+
+BEGIN {
+    *CORE::GLOBAL::time = sub () { $NOW // CORE::time() }
+}
+
 # name => (size, mtime) for every file under the repo dirs this test could
 # plausibly disturb.  Cheap enough, and it is the only real proof of isolation.
 sub _snapshot {
@@ -1196,8 +1204,7 @@ subtest 'invoice' => sub {
     my $title = 'Spec Invoice Series';
     _make_series( 'invoice', 'specinvoice', 'invoice.tx', $title ) or return;
 
-    my $child = _save_post(
-        'invoice child',
+    my %invoice = (
         form          => 'invoice.tx',
         title         => 'Spec Invoice Child',
         data          => [ "Widget assembly\nPrice: \$420", "Shipping\nPrice: \$80" ],
@@ -1208,7 +1215,16 @@ subtest 'invoice' => sub {
         visibility    => 'public',
         tags          => ['specinvoice'],
         to            => '/specinvoice',
-    ) or return;
+    );
+
+    my $sent  = time() - 10 * 86400;
+    my $child = do { local $NOW = $sent; _save_post( 'invoice child', %invoice ) }
+      or return;
+    is( $child->{created}, $sent, 'the first save is stamped with the clock the test set' );
+
+    $child = _save_post( 'invoice child, edited', %invoice, id => $child->{id} ) or return;
+    is( $child->{created}, $sent, 'an edit keeps the date the invoice was first made' );
+    cmp_ok( $child->{modified}, '>', $sent, 'and the edit carries a later one' );
 
     my $body = _series_page( 'invoice', 'specinvoice', $title, 1 ) or return;
 
@@ -1222,6 +1238,9 @@ subtest 'invoice' => sub {
 
     like( $body, qr/Widget assembly/, 'line items rendered' );
     like( $body, qr/Total: \$500/,    'total summed from the line item prices' );
+
+    my $due = $child->{modified} + 30 * 86400;
+    like( $body, qr{Due: <span class="unixtimestamp">\Q$due\E</span>}, 'due date counts from the latest edit, not the first save' );
 };
 
 subtest 'spec_widget (the wizard-built type)' => sub {

+ 4 - 2
www/templates/html/components/forms/invoice.tx

@@ -7,6 +7,8 @@
             <img src="<: $post.preview :>" class="responsive-img" loading="lazy" />
         : }
 
+        : # An edit re-sends the invoice, so it is dated, and falls due, from the newest version.
+        : my $sent = $post.modified // $post.created;
         <div class="postData responsive-text" id="postData-<: $post.id :>">
             <div class="table">
                 <div class="table-row">
@@ -17,10 +19,10 @@
                 </div>
                 <div class="table-row">
                     <div class="table-cell underline">
-                        Created: <span class="unixtimestamp"><: $post.created :></span><br />
+                        Created: <span class="unixtimestamp"><: $sent :></span><br />
                     </div>
                     <div class="table-cell underline">
-                        Due: <span class="unixtimestamp"><: $post.created + ($post.due_days * 86400 ) :></span>
+                        Due: <span class="unixtimestamp"><: $sent + ($post.due_days * 86400 ) :></span>
                     </div>
                 </div>
                 <div class="table-row">