mirror of
				https://github.com/paperless-ngx/paperless-ngx.git
				synced 2025-11-04 03:27:12 -05:00 
			
		
		
		
	use created_date
This commit is contained in:
		
							parent
							
								
									bb15b744c8
								
							
						
					
					
						commit
						2ca691d3b8
					
				@ -12,7 +12,7 @@
 | 
				
			|||||||
    </thead>
 | 
					    </thead>
 | 
				
			||||||
    <tbody>
 | 
					    <tbody>
 | 
				
			||||||
      <tr *ngFor="let doc of documents" (click)="openDocumentsService.openDocument(doc)">
 | 
					      <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>
 | 
					        <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>
 | 
					      </tr>
 | 
				
			||||||
    </tbody>
 | 
					    </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-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-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"
 | 
					                        <app-input-select [items]="correspondents" i18n-title title="Correspondent" formControlName="correspondent" [allowNull]="true"
 | 
				
			||||||
                            (createNew)="createCorrespondent($event)" [suggestions]="suggestions?.correspondents"></app-input-select>
 | 
					                            (createNew)="createCorrespondent($event)" [suggestions]="suggestions?.correspondents"></app-input-select>
 | 
				
			||||||
                        <app-input-select [items]="documentTypes" i18n-title title="Document type" formControlName="document_type" [allowNull]="true"
 | 
					                        <app-input-select [items]="documentTypes" i18n-title title="Document type" formControlName="document_type" [allowNull]="true"
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,6 @@ import {
 | 
				
			|||||||
} from 'rxjs/operators'
 | 
					} from 'rxjs/operators'
 | 
				
			||||||
import { PaperlessDocumentSuggestions } from 'src/app/data/paperless-document-suggestions'
 | 
					import { PaperlessDocumentSuggestions } from 'src/app/data/paperless-document-suggestions'
 | 
				
			||||||
import { FILTER_FULLTEXT_MORELIKE } from 'src/app/data/filter-rule-type'
 | 
					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'
 | 
					import { QueryParamsService } from 'src/app/services/query-params.service'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Component({
 | 
					@Component({
 | 
				
			||||||
@ -72,7 +71,7 @@ export class DocumentDetailComponent
 | 
				
			|||||||
  documentForm: FormGroup = new FormGroup({
 | 
					  documentForm: FormGroup = new FormGroup({
 | 
				
			||||||
    title: new FormControl(''),
 | 
					    title: new FormControl(''),
 | 
				
			||||||
    content: new FormControl(''),
 | 
					    content: new FormControl(''),
 | 
				
			||||||
    created: new FormControl(),
 | 
					    created_date: new FormControl(),
 | 
				
			||||||
    correspondent: new FormControl(),
 | 
					    correspondent: new FormControl(),
 | 
				
			||||||
    document_type: new FormControl(),
 | 
					    document_type: new FormControl(),
 | 
				
			||||||
    archive_serial_number: new FormControl(),
 | 
					    archive_serial_number: new FormControl(),
 | 
				
			||||||
@ -137,27 +136,8 @@ export class DocumentDetailComponent
 | 
				
			|||||||
  ngOnInit(): void {
 | 
					  ngOnInit(): void {
 | 
				
			||||||
    this.documentForm.valueChanges
 | 
					    this.documentForm.valueChanges
 | 
				
			||||||
      .pipe(takeUntil(this.unsubscribeNotifier))
 | 
					      .pipe(takeUntil(this.unsubscribeNotifier))
 | 
				
			||||||
      .subscribe((changes) => {
 | 
					      .subscribe(() => {
 | 
				
			||||||
        this.error = null
 | 
					        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)
 | 
					        Object.assign(this.document, this.documentForm.value)
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -223,25 +203,17 @@ export class DocumentDetailComponent
 | 
				
			|||||||
              },
 | 
					              },
 | 
				
			||||||
            })
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          this.ogDate = new Date(normalizeDateStr(doc.created.toString()))
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          // Initialize dirtyCheck
 | 
					          // Initialize dirtyCheck
 | 
				
			||||||
          this.store = new BehaviorSubject({
 | 
					          this.store = new BehaviorSubject({
 | 
				
			||||||
            title: doc.title,
 | 
					            title: doc.title,
 | 
				
			||||||
            content: doc.content,
 | 
					            content: doc.content,
 | 
				
			||||||
            created: this.ogDate.toISOString(),
 | 
					            created_date: doc.created_date,
 | 
				
			||||||
            correspondent: doc.correspondent,
 | 
					            correspondent: doc.correspondent,
 | 
				
			||||||
            document_type: doc.document_type,
 | 
					            document_type: doc.document_type,
 | 
				
			||||||
            archive_serial_number: doc.archive_serial_number,
 | 
					            archive_serial_number: doc.archive_serial_number,
 | 
				
			||||||
            tags: [...doc.tags],
 | 
					            tags: [...doc.tags],
 | 
				
			||||||
          })
 | 
					          })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          // start with ISO8601 string
 | 
					 | 
				
			||||||
          this.documentForm.patchValue(
 | 
					 | 
				
			||||||
            { created: this.ogDate.toISOString() },
 | 
					 | 
				
			||||||
            { emitEvent: false }
 | 
					 | 
				
			||||||
          )
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
          this.isDirty$ = dirtyCheck(
 | 
					          this.isDirty$ = dirtyCheck(
 | 
				
			||||||
            this.documentForm,
 | 
					            this.documentForm,
 | 
				
			||||||
            this.store.asObservable()
 | 
					            this.store.asObservable()
 | 
				
			||||||
 | 
				
			|||||||
@ -32,8 +32,12 @@ export interface PaperlessDocument extends ObjectWithId {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  checksum?: string
 | 
					  checksum?: string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // UTC
 | 
				
			||||||
  created?: Date
 | 
					  created?: Date
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // localized date
 | 
				
			||||||
 | 
					  created_date?: Date
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  modified?: Date
 | 
					  modified?: Date
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  added?: Date
 | 
					  added?: Date
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,6 @@
 | 
				
			|||||||
import { DatePipe } from '@angular/common'
 | 
					import { DatePipe } from '@angular/common'
 | 
				
			||||||
import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core'
 | 
					import { Inject, LOCALE_ID, Pipe, PipeTransform } from '@angular/core'
 | 
				
			||||||
import { SettingsService, SETTINGS_KEYS } from '../services/settings.service'
 | 
					import { SettingsService, SETTINGS_KEYS } from '../services/settings.service'
 | 
				
			||||||
import { normalizeDateStr } from '../utils/date'
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const FORMAT_TO_ISO_FORMAT = {
 | 
					const FORMAT_TO_ISO_FORMAT = {
 | 
				
			||||||
  longDate: 'y-MM-dd',
 | 
					  longDate: 'y-MM-dd',
 | 
				
			||||||
@ -34,7 +33,6 @@ export class CustomDatePipe implements PipeTransform {
 | 
				
			|||||||
      this.settings.get(SETTINGS_KEYS.DATE_LOCALE) ||
 | 
					      this.settings.get(SETTINGS_KEYS.DATE_LOCALE) ||
 | 
				
			||||||
      this.defaultLocale
 | 
					      this.defaultLocale
 | 
				
			||||||
    let f = format || this.settings.get(SETTINGS_KEYS.DATE_FORMAT)
 | 
					    let f = format || this.settings.get(SETTINGS_KEYS.DATE_FORMAT)
 | 
				
			||||||
    if (typeof value == 'string') value = normalizeDateStr(value)
 | 
					 | 
				
			||||||
    if (l == 'iso-8601') {
 | 
					    if (l == 'iso-8601') {
 | 
				
			||||||
      return this.datePipe.transform(value, FORMAT_TO_ISO_FORMAT[f], timezone)
 | 
					      return this.datePipe.transform(value, FORMAT_TO_ISO_FORMAT[f], timezone)
 | 
				
			||||||
    } else {
 | 
					    } 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> {
 | 
					export class ISODateTimeAdapter extends NgbDateAdapter<string> {
 | 
				
			||||||
  fromModel(value: string | null): NgbDateStruct | null {
 | 
					  fromModel(value: string | null): NgbDateStruct | null {
 | 
				
			||||||
    if (value) {
 | 
					    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)
 | 
					        let date = new Date(value)
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
          day: date.getDate(),
 | 
					          day: date.getDate(),
 | 
				
			||||||
          month: date.getMonth() + 1,
 | 
					          month: date.getMonth() + 1,
 | 
				
			||||||
          year: date.getFullYear(),
 | 
					          year: date.getFullYear(),
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
      return null
 | 
					      return null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  toModel(date: NgbDateStruct | null): string | null {
 | 
					  toModel(date: NgbDateStruct | null): string | null {
 | 
				
			||||||
    return date
 | 
					    return date ? [date.year, date.month, date.day].join('-') : null
 | 
				
			||||||
      ? new Date(date.year, date.month - 1, date.day).toISOString()
 | 
					 | 
				
			||||||
      : null
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -279,6 +279,10 @@ class Document(models.Model):
 | 
				
			|||||||
    def thumbnail_file(self):
 | 
					    def thumbnail_file(self):
 | 
				
			||||||
        return open(self.thumbnail_path, "rb")
 | 
					        return open(self.thumbnail_path, "rb")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def created_date(self):
 | 
				
			||||||
 | 
					        return timezone.localdate(self.created)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Log(models.Model):
 | 
					class Log(models.Model):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,10 @@
 | 
				
			|||||||
 | 
					import datetime
 | 
				
			||||||
import math
 | 
					import math
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import magic
 | 
					import magic
 | 
				
			||||||
 | 
					from dateutil import tz
 | 
				
			||||||
 | 
					from django.conf import settings
 | 
				
			||||||
from django.utils.text import slugify
 | 
					from django.utils.text import slugify
 | 
				
			||||||
from django.utils.translation import gettext as _
 | 
					from django.utils.translation import gettext as _
 | 
				
			||||||
from rest_framework import serializers
 | 
					from rest_framework import serializers
 | 
				
			||||||
@ -206,6 +209,7 @@ class DocumentSerializer(DynamicFieldsModelSerializer):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    original_file_name = SerializerMethodField()
 | 
					    original_file_name = SerializerMethodField()
 | 
				
			||||||
    archived_file_name = SerializerMethodField()
 | 
					    archived_file_name = SerializerMethodField()
 | 
				
			||||||
 | 
					    created_date = serializers.DateField()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_original_file_name(self, obj):
 | 
					    def get_original_file_name(self, obj):
 | 
				
			||||||
        return obj.get_public_filename()
 | 
					        return obj.get_public_filename()
 | 
				
			||||||
@ -216,6 +220,16 @@ class DocumentSerializer(DynamicFieldsModelSerializer):
 | 
				
			|||||||
        else:
 | 
					        else:
 | 
				
			||||||
            return None
 | 
					            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:
 | 
					    class Meta:
 | 
				
			||||||
        model = Document
 | 
					        model = Document
 | 
				
			||||||
        depth = 1
 | 
					        depth = 1
 | 
				
			||||||
@ -227,6 +241,7 @@ class DocumentSerializer(DynamicFieldsModelSerializer):
 | 
				
			|||||||
            "content",
 | 
					            "content",
 | 
				
			||||||
            "tags",
 | 
					            "tags",
 | 
				
			||||||
            "created",
 | 
					            "created",
 | 
				
			||||||
 | 
					            "created_date",
 | 
				
			||||||
            "modified",
 | 
					            "modified",
 | 
				
			||||||
            "added",
 | 
					            "added",
 | 
				
			||||||
            "archive_serial_number",
 | 
					            "archive_serial_number",
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user