mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-03 03:16:10 -06:00 
			
		
		
		
	use created_date
This commit is contained in:
		@@ -12,7 +12,7 @@
 | 
			
		||||
    </thead>
 | 
			
		||||
    <tbody>
 | 
			
		||||
      <tr *ngFor="let doc of documents" (click)="openDocumentsService.openDocument(doc)">
 | 
			
		||||
        <td>{{doc.created | customDate}}</td>
 | 
			
		||||
        <td>{{doc.created_date | customDate}}</td>
 | 
			
		||||
        <td>{{doc.title | documentTitle}}<app-tag [tag]="t" *ngFor="let t of doc.tags$ | async" class="ms-1" (click)="clickTag(t); $event.stopPropagation();"></app-tag></td>
 | 
			
		||||
      </tr>
 | 
			
		||||
    </tbody>
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,7 @@
 | 
			
		||||
 | 
			
		||||
                        <app-input-text #inputTitle i18n-title title="Title" formControlName="title" (keyup)="titleKeyUp($event)" [error]="error?.title"></app-input-text>
 | 
			
		||||
                        <app-input-number i18n-title title="Archive serial number" [error]="error?.archive_serial_number" formControlName='archive_serial_number'></app-input-number>
 | 
			
		||||
                        <app-input-date i18n-title title="Date created" formControlName="created" [error]="error?.created"></app-input-date>
 | 
			
		||||
                        <app-input-date i18n-title title="Date created" formControlName="created_date" [error]="error?.created"></app-input-date>
 | 
			
		||||
                        <app-input-select [items]="correspondents" i18n-title title="Correspondent" formControlName="correspondent" [allowNull]="true"
 | 
			
		||||
                            (createNew)="createCorrespondent($event)" [suggestions]="suggestions?.correspondents"></app-input-select>
 | 
			
		||||
                        <app-input-select [items]="documentTypes" i18n-title title="Document type" formControlName="document_type" [allowNull]="true"
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,6 @@ import {
 | 
			
		||||
} from 'rxjs/operators'
 | 
			
		||||
import { PaperlessDocumentSuggestions } from 'src/app/data/paperless-document-suggestions'
 | 
			
		||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'
 | 
			
		||||
import { normalizeDateStr } from 'src/app/utils/date'
 | 
			
		||||
import { QueryParamsService } from 'src/app/services/query-params.service'
 | 
			
		||||
 | 
			
		||||
@Component({
 | 
			
		||||
@@ -72,7 +71,7 @@ export class DocumentDetailComponent
 | 
			
		||||
  documentForm: FormGroup = new FormGroup({
 | 
			
		||||
    title: new FormControl(''),
 | 
			
		||||
    content: new FormControl(''),
 | 
			
		||||
    created: new FormControl(),
 | 
			
		||||
    created_date: new FormControl(),
 | 
			
		||||
    correspondent: new FormControl(),
 | 
			
		||||
    document_type: new FormControl(),
 | 
			
		||||
    archive_serial_number: new FormControl(),
 | 
			
		||||
@@ -137,27 +136,8 @@ export class DocumentDetailComponent
 | 
			
		||||
  ngOnInit(): void {
 | 
			
		||||
    this.documentForm.valueChanges
 | 
			
		||||
      .pipe(takeUntil(this.unsubscribeNotifier))
 | 
			
		||||
      .subscribe((changes) => {
 | 
			
		||||
      .subscribe(() => {
 | 
			
		||||
        this.error = null
 | 
			
		||||
        if (this.ogDate) {
 | 
			
		||||
          try {
 | 
			
		||||
            let newDate = new Date(normalizeDateStr(changes['created']))
 | 
			
		||||
            newDate.setHours(
 | 
			
		||||
              this.ogDate.getHours(),
 | 
			
		||||
              this.ogDate.getMinutes(),
 | 
			
		||||
              this.ogDate.getSeconds(),
 | 
			
		||||
              this.ogDate.getMilliseconds()
 | 
			
		||||
            )
 | 
			
		||||
            this.documentForm.patchValue(
 | 
			
		||||
              { created: newDate.toISOString() },
 | 
			
		||||
              { emitEvent: false }
 | 
			
		||||
            )
 | 
			
		||||
          } catch (e) {
 | 
			
		||||
            // catch this before we try to save and simulate an api error
 | 
			
		||||
            this.error = { created: e.message }
 | 
			
		||||
          }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Object.assign(this.document, this.documentForm.value)
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
@@ -223,25 +203,17 @@ export class DocumentDetailComponent
 | 
			
		||||
              },
 | 
			
		||||
            })
 | 
			
		||||
 | 
			
		||||
          this.ogDate = new Date(normalizeDateStr(doc.created.toString()))
 | 
			
		||||
 | 
			
		||||
          // Initialize dirtyCheck
 | 
			
		||||
          this.store = new BehaviorSubject({
 | 
			
		||||
            title: doc.title,
 | 
			
		||||
            content: doc.content,
 | 
			
		||||
            created: this.ogDate.toISOString(),
 | 
			
		||||
            created_date: doc.created_date,
 | 
			
		||||
            correspondent: doc.correspondent,
 | 
			
		||||
            document_type: doc.document_type,
 | 
			
		||||
            archive_serial_number: doc.archive_serial_number,
 | 
			
		||||
            tags: [...doc.tags],
 | 
			
		||||
          })
 | 
			
		||||
 | 
			
		||||
          // start with ISO8601 string
 | 
			
		||||
          this.documentForm.patchValue(
 | 
			
		||||
            { created: this.ogDate.toISOString() },
 | 
			
		||||
            { emitEvent: false }
 | 
			
		||||
          )
 | 
			
		||||
 | 
			
		||||
          this.isDirty$ = dirtyCheck(
 | 
			
		||||
            this.documentForm,
 | 
			
		||||
            this.store.asObservable()
 | 
			
		||||
 
 | 
			
		||||
@@ -32,8 +32,12 @@ export interface PaperlessDocument extends ObjectWithId {
 | 
			
		||||
 | 
			
		||||
  checksum?: string
 | 
			
		||||
 | 
			
		||||
  // UTC
 | 
			
		||||
  created?: Date
 | 
			
		||||
 | 
			
		||||
  // localized date
 | 
			
		||||
  created_date?: Date
 | 
			
		||||
 | 
			
		||||
  modified?: Date
 | 
			
		||||
 | 
			
		||||
  added?: Date
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
import { DatePipe } from '@angular/common'
 | 
			
		||||
import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core'
 | 
			
		||||
import { SettingsService, SETTINGS_KEYS } from '../services/settings.service'
 | 
			
		||||
import { normalizeDateStr } from '../utils/date'
 | 
			
		||||
 | 
			
		||||
const FORMAT_TO_ISO_FORMAT = {
 | 
			
		||||
  longDate: 'y-MM-dd',
 | 
			
		||||
@@ -34,7 +33,6 @@ export class CustomDatePipe implements PipeTransform {
 | 
			
		||||
      this.settings.get(SETTINGS_KEYS.DATE_LOCALE) ||
 | 
			
		||||
      this.defaultLocale
 | 
			
		||||
    let f = format || this.settings.get(SETTINGS_KEYS.DATE_FORMAT)
 | 
			
		||||
    if (typeof value == 'string') value = normalizeDateStr(value)
 | 
			
		||||
    if (l == 'iso-8601') {
 | 
			
		||||
      return this.datePipe.transform(value, FORMAT_TO_ISO_FORMAT[f], timezone)
 | 
			
		||||
    } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,5 +0,0 @@
 | 
			
		||||
// see https://github.com/dateutil/dateutil/issues/878 , JS Date does not
 | 
			
		||||
// seem to accept these strings as valid dates so we must normalize offset
 | 
			
		||||
export function normalizeDateStr(dateStr: string): string {
 | 
			
		||||
  return dateStr.replace(/[\+-](\d\d):\d\d:\d\d/gm, `-$1:00`)
 | 
			
		||||
}
 | 
			
		||||
@@ -5,20 +5,27 @@ import { NgbDateAdapter, NgbDateStruct } from '@ng-bootstrap/ng-bootstrap'
 | 
			
		||||
export class ISODateTimeAdapter extends NgbDateAdapter<string> {
 | 
			
		||||
  fromModel(value: string | null): NgbDateStruct | null {
 | 
			
		||||
    if (value) {
 | 
			
		||||
      if (value.match(/\d\d\d\d\-\d\d\-\d\d/g)) {
 | 
			
		||||
        const segs = value.split('-')
 | 
			
		||||
        return {
 | 
			
		||||
          year: parseInt(segs[0]),
 | 
			
		||||
          month: parseInt(segs[1]),
 | 
			
		||||
          day: parseInt(segs[2]),
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        let date = new Date(value)
 | 
			
		||||
        return {
 | 
			
		||||
          day: date.getDate(),
 | 
			
		||||
          month: date.getMonth() + 1,
 | 
			
		||||
          year: date.getFullYear(),
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
    } else {
 | 
			
		||||
      return null
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  toModel(date: NgbDateStruct | null): string | null {
 | 
			
		||||
    return date
 | 
			
		||||
      ? new Date(date.year, date.month - 1, date.day).toISOString()
 | 
			
		||||
      : null
 | 
			
		||||
    return date ? [date.year, date.month, date.day].join('-') : null
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -279,6 +279,10 @@ class Document(models.Model):
 | 
			
		||||
    def thumbnail_file(self):
 | 
			
		||||
        return open(self.thumbnail_path, "rb")
 | 
			
		||||
 | 
			
		||||
    @property
 | 
			
		||||
    def created_date(self):
 | 
			
		||||
        return timezone.localdate(self.created)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class Log(models.Model):
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,10 @@
 | 
			
		||||
import datetime
 | 
			
		||||
import math
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
import magic
 | 
			
		||||
from dateutil import tz
 | 
			
		||||
from django.conf import settings
 | 
			
		||||
from django.utils.text import slugify
 | 
			
		||||
from django.utils.translation import gettext as _
 | 
			
		||||
from rest_framework import serializers
 | 
			
		||||
@@ -206,6 +209,7 @@ class DocumentSerializer(DynamicFieldsModelSerializer):
 | 
			
		||||
 | 
			
		||||
    original_file_name = SerializerMethodField()
 | 
			
		||||
    archived_file_name = SerializerMethodField()
 | 
			
		||||
    created_date = serializers.DateField()
 | 
			
		||||
 | 
			
		||||
    def get_original_file_name(self, obj):
 | 
			
		||||
        return obj.get_public_filename()
 | 
			
		||||
@@ -216,6 +220,16 @@ class DocumentSerializer(DynamicFieldsModelSerializer):
 | 
			
		||||
        else:
 | 
			
		||||
            return None
 | 
			
		||||
 | 
			
		||||
    def update(self, instance, validated_data):
 | 
			
		||||
        if "created_date" in validated_data and "created" not in validated_data:
 | 
			
		||||
            new_datetime = datetime.datetime.combine(
 | 
			
		||||
                validated_data.get("created_date"),
 | 
			
		||||
                datetime.time(0, 0, 0, 0, tz.gettz(settings.TIME_ZONE)),
 | 
			
		||||
            )
 | 
			
		||||
            instance.created = new_datetime
 | 
			
		||||
            instance.save()
 | 
			
		||||
        return instance
 | 
			
		||||
 | 
			
		||||
    class Meta:
 | 
			
		||||
        model = Document
 | 
			
		||||
        depth = 1
 | 
			
		||||
@@ -227,6 +241,7 @@ class DocumentSerializer(DynamicFieldsModelSerializer):
 | 
			
		||||
            "content",
 | 
			
		||||
            "tags",
 | 
			
		||||
            "created",
 | 
			
		||||
            "created_date",
 | 
			
		||||
            "modified",
 | 
			
		||||
            "added",
 | 
			
		||||
            "archive_serial_number",
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user