mirror of
https://github.com/TheAnachronism/docspell.git
synced 2025-02-15 20:33:26 +00:00
Update state and proposals only on invalid items
Invalid items are those that are not ready, and not shown to the user. When changing metadata, it should only be changed, if the item was not already shown to the user.
This commit is contained in:
parent
855d4eefa8
commit
25d089da6c
@ -1,11 +1,18 @@
|
||||
package docspell.common
|
||||
|
||||
import io.circe.{Decoder, Encoder}
|
||||
import cats.data.NonEmptyList
|
||||
|
||||
sealed trait ItemState { self: Product =>
|
||||
|
||||
final def name: String =
|
||||
productPrefix.toLowerCase
|
||||
|
||||
def isValid: Boolean =
|
||||
ItemState.validStates.exists(_ == this)
|
||||
|
||||
def isInvalid: Boolean =
|
||||
ItemState.invalidStates.exists(_ == this)
|
||||
}
|
||||
|
||||
object ItemState {
|
||||
@ -24,8 +31,11 @@ object ItemState {
|
||||
case _ => Left(s"Invalid item state: $str")
|
||||
}
|
||||
|
||||
val validStates: Seq[ItemState] =
|
||||
Seq(Created, Confirmed)
|
||||
val validStates: NonEmptyList[ItemState] =
|
||||
NonEmptyList.of(Created, Confirmed)
|
||||
|
||||
val invalidStates: NonEmptyList[ItemState] =
|
||||
NonEmptyList.of(Premature, Processing)
|
||||
|
||||
def unsafe(str: String): ItemState =
|
||||
fromString(str).fold(sys.error, identity)
|
||||
|
@ -71,7 +71,7 @@ object NotifyDueItemsTask {
|
||||
QItem.Query
|
||||
.empty(ctx.args.account.collective)
|
||||
.copy(
|
||||
states = ItemState.validStates,
|
||||
states = ItemState.validStates.toList,
|
||||
tagsInclude = ctx.args.tagsInclude,
|
||||
tagsExclude = ctx.args.tagsExclude,
|
||||
dueDateFrom = ctx.args.daysBack.map(back => now - Duration.days(back.toLong)),
|
||||
|
@ -25,7 +25,11 @@ object ItemHandler {
|
||||
def itemStateTask[F[_]: Sync, A](
|
||||
state: ItemState
|
||||
)(data: ItemData): Task[F, A, ItemData] =
|
||||
Task(ctx => ctx.store.transact(RItem.updateState(data.item.id, state)).map(_ => data))
|
||||
Task(ctx =>
|
||||
ctx.store
|
||||
.transact(RItem.updateState(data.item.id, state, ItemState.invalidStates))
|
||||
.map(_ => data)
|
||||
)
|
||||
|
||||
def isLastRetry[F[_]: Sync, A](ctx: Context[F, A]): F[Boolean] =
|
||||
for {
|
||||
|
@ -9,21 +9,26 @@ import docspell.store.records.RItem
|
||||
object LinkProposal {
|
||||
|
||||
def apply[F[_]: Sync](data: ItemData): Task[F, ProcessItemArgs, ItemData] =
|
||||
Task { ctx =>
|
||||
// sort by weight; order of equal weights is not important, just
|
||||
// choose one others are then suggestions
|
||||
// doc-date is only set when given explicitely, not from "guessing"
|
||||
val proposals = MetaProposalList
|
||||
.flatten(data.metas.map(_.proposals))
|
||||
.filter(_.proposalType != MetaProposalType.DocDate)
|
||||
.sortByWeights
|
||||
if (data.item.state.isValid)
|
||||
Task
|
||||
.log[F, ProcessItemArgs](_.debug(s"Not linking proposals on existing item"))
|
||||
.map(_ => data)
|
||||
else
|
||||
Task { ctx =>
|
||||
// sort by weight; order of equal weights is not important, just
|
||||
// choose one others are then suggestions
|
||||
// doc-date is only set when given explicitely, not from "guessing"
|
||||
val proposals = MetaProposalList
|
||||
.flatten(data.metas.map(_.proposals))
|
||||
.filter(_.proposalType != MetaProposalType.DocDate)
|
||||
.sortByWeights
|
||||
|
||||
ctx.logger.info(s"Starting linking proposals") *>
|
||||
MetaProposalType.all
|
||||
.traverse(applyValue(data, proposals, ctx))
|
||||
.map(result => ctx.logger.info(s"Results from proposal processing: $result"))
|
||||
.map(_ => data)
|
||||
}
|
||||
ctx.logger.info(s"Starting linking proposals") *>
|
||||
MetaProposalType.all
|
||||
.traverse(applyValue(data, proposals, ctx))
|
||||
.map(result => ctx.logger.info(s"Results from proposal processing: $result"))
|
||||
.map(_ => data)
|
||||
}
|
||||
|
||||
def applyValue[F[_]: Sync](
|
||||
data: ItemData,
|
||||
@ -40,8 +45,9 @@ object LinkProposal {
|
||||
Result.single(mpt)
|
||||
)
|
||||
case Some(a) =>
|
||||
val ids = a.values.map(_.ref.id.id)
|
||||
ctx.logger.info(
|
||||
s"Found many (${a.size}, ${a.values.map(_.ref.id.id)}) candidates for ${a.proposalType}. Setting first."
|
||||
s"Found many (${a.size}, ${ids}) candidates for ${a.proposalType}. Setting first."
|
||||
) *>
|
||||
setItemMeta(data.item.id, ctx, a.proposalType, a.values.head.ref.id).map(_ =>
|
||||
Result.multiple(mpt)
|
||||
|
@ -109,7 +109,7 @@ trait Conversions {
|
||||
coll,
|
||||
m.name,
|
||||
if (m.inbox) Seq(ItemState.Created)
|
||||
else ItemState.validStates,
|
||||
else ItemState.validStates.toList,
|
||||
m.direction,
|
||||
m.corrPerson,
|
||||
m.corrOrg,
|
||||
|
@ -1,7 +1,8 @@
|
||||
package docspell.store.records
|
||||
|
||||
import cats.implicits._
|
||||
import cats.data.NonEmptyList
|
||||
import cats.effect.Sync
|
||||
import cats.implicits._
|
||||
import doobie._
|
||||
import doobie.implicits._
|
||||
import docspell.common._
|
||||
@ -110,12 +111,16 @@ object RItem {
|
||||
def getCollective(itemId: Ident): ConnectionIO[Option[Ident]] =
|
||||
selectSimple(List(cid), table, id.is(itemId)).query[Ident].option
|
||||
|
||||
def updateState(itemId: Ident, itemState: ItemState): ConnectionIO[Int] =
|
||||
def updateState(
|
||||
itemId: Ident,
|
||||
itemState: ItemState,
|
||||
existing: NonEmptyList[ItemState]
|
||||
): ConnectionIO[Int] =
|
||||
for {
|
||||
t <- currentTime
|
||||
n <- updateRow(
|
||||
table,
|
||||
id.is(itemId),
|
||||
and(id.is(itemId), state.isIn(existing)),
|
||||
commas(state.setTo(itemState), updated.setTo(t))
|
||||
).update.run
|
||||
} yield n
|
||||
|
Loading…
Reference in New Issue
Block a user