Class ExportQueueDAO

java.lang.Object
ru.bgcrm.dao.CommonDAO
org.bgerp.plugin.inventoru.sync1c.dao.ExportQueueDAO

public class ExportQueueDAO extends CommonDAO
DAO for ExportQueue (inventoru_sync1c_export_queue table).
  • Constructor Details

    • ExportQueueDAO

      public ExportQueueDAO(Connection con)
  • Method Details

    • add

      public void add(int processId, int instanceId, String warehouseId, int storeId) throws SQLException
      Inserts or resets a pending queue entry for the given process/instance/store combination. An existing record is put back in line so the process can be exported again after its status was reverted and re-applied — but not a settled one ('success', 'unposted', 'local'): a second status event in the write-off status would otherwise send the same write-off to 1C twice, and over a 'local' one it would erase the only record that the write-off was made deliberately without 1C and re-open a decision already carried out in the ledger. Settled entries are reversed when the process leaves the status, and enqueued afresh after that.
      Throws:
      SQLException
    • addSuccess

      public boolean addSuccess(int processId, int instanceId, String warehouseId, int storeId) throws SQLException
      Inserts (or resets) a queue entry directly in 'success' status — nothing is sent anywhere. Used for OData connectors, where the write-off is local-only (the protocol has no push channel to 1C): the 'success' row must still exist so hasWriteoffInErp(int) keeps locking materials editing and the reversal path in Sync1cExportListener works exactly as for the HS/File protocols. Two statements instead of one upsert: the claiming UPDATE is a locking (current) read, so a concurrent duplicate call blocks on the row lock, then sees status='success' and gets 0 affected rows — regardless of the transaction's REPEATABLE READ snapshot, which a SELECT-based check could be fooled by (same race class as finalizePendingStatus(int, String, int, String)).
      Returns:
      true if this call claimed the transition to 'success' — the caller must create the local writeoff movements ONLY then; false = another request already did it.
      Throws:
      SQLException
    • updateWarehouseId

      public void updateWarehouseId(int id, String warehouseId) throws SQLException
      Stores the identifier that actually went to 1C — it is resolved at send time from the store's parameter, and keeping it here makes the queue screen and the CSV export show what was sent rather than what the mapping happened to hold when the entry was created.
      Throws:
      SQLException
    • get

      public ExportQueue get(int id) throws SQLException
      Throws:
      SQLException
    • getPendingByInstance

      public List<ExportQueue> getPendingByInstance(int instanceId) throws SQLException
      Returns all pending queue entries for one instance, regardless of attempts — used by the File-protocol CSV export, which has no attempts/retry concept (there's no HTTP call to fail).
      Throws:
      SQLException
    • getPendingByProtocol

      public List<ExportQueue> getPendingByProtocol(int maxAttempts, String protocol) throws SQLException
      Returns pending queue entries with attempts less than maxAttempts, restricted to enabled instances using the given protocol. Used by ExportPoller so it only auto-sends for HS-protocol instances — File-protocol instances are confirmed manually instead. Disabled instances are left alone, the way the import side already leaves them (EngineerWarehouseDAO.isSerialMasterStore(int)): switching an exchange off means "do not talk to this 1C", and the poller went on sending write-offs to it. Their entries then wait for a person — that is what "Подтвердить: проведено в 1С" and "Списать без 1С" on the queue screen are for; nothing about a write-off is decided behind their back.
      Throws:
      SQLException
    • updateStatus

      public void updateStatus(int id, String status, int attempts, String error) throws SQLException
      Updates status, attempts count and error text for a queue entry.
      Throws:
      SQLException
    • isPending

      public boolean isPending(int id) throws SQLException
      Returns true if the entry is still pending. Used by ExportPoller right before sending to 1C, to catch a concurrent cancellation (process moved for rework) that happened after the poller took its initial snapshot of pending entries.
      Throws:
      SQLException
    • finalizePendingStatus

      public boolean finalizePendingStatus(int id, String status, int attempts, String error) throws SQLException
      Finalizes the outcome of processing a pending entry (success/failed), but only if it's still pending. If a concurrent cancellation flipped it to 'cancelled' in the meantime, this is a no-op — the cancellation wins and doesn't get silently overwritten back to success/failed.
      Returns:
      true if this call actually claimed the row (it was still 'pending'), false if a concurrent request already moved it elsewhere first — callers doing balance-affecting work (e.g. creating writeoff movements) must skip that work when this returns false, otherwise two racing callers can both act on the same entry before either commits.
      Throws:
      SQLException
    • finalizePendingStatus

      public boolean finalizePendingStatus(int id, String status, int attempts, String error, int userId) throws SQLException
      The same claim, naming the person who made it: the poller closes an entry on its own and leaves 0, a hand-made confirmation or a write-off without 1C is somebody's decision, and the ledger shows only that the goods went, never who decided they should.
      Parameters:
      userId - who is closing the entry, 0 for the poller.
      Throws:
      SQLException
    • finalizeOpenStatus

      public boolean finalizeOpenStatus(int id, String status, int attempts, String error, int userId) throws SQLException
      The same claim over an entry that is still open — pending, or failed after the tries ran out. A failed one is the case this exists for: 1C unreachable, attempts exhausted, and the reserve of a finished job standing until a person decides what to do with it.
      Throws:
      SQLException
    • claimStatus

      public boolean claimStatus(int id, String from, String to) throws SQLException
      Moves the entry from one status to another only if it is still in the first one — the claim that lets exactly one of two concurrent requests do the balance-affecting work.
      Returns:
      true if this call made the transition
      Throws:
      SQLException
    • getListByInstance

      public List<ExportQueue> getListByInstance(int instanceId) throws SQLException
      Returns queue entries for a given instance (latest 100, newest first).
      Throws:
      SQLException
    • getListByProcessId

      public List<ExportQueue> getListByProcessId(int processId) throws SQLException
      All queue entries of one process, newest first. A process reserving from two stores has one entry per store (the unique key is process + instance + store), so what is asked of a person is a list, never a single row. The lookup runs on the leftmost column of uq_process_instance_store — no index of its own is needed.
      Throws:
      SQLException
    • hasWriteoffInErp

      public boolean hasWriteoffInErp(int processId) throws SQLException
      Returns true if the write-off of the process is already settled and must not be edited any more. Used to lock materials editing regardless of the process's current status — status alone isn't reliable once a process is moved back after export. Three cases count, for three different reasons: 'success' — sent and written off here; 'unposted' — 1C already holds it, only ERP lags behind; 'local' — written off here by hand, 1C will never hold it. The last one locks exactly like the others: the movements exist, and editing materials over them would take the ledger apart.
      Throws:
      SQLException
    • markReversed

      public void markReversed(int processId) throws SQLException
      Marks settled entries for the process as reversed, so hasWriteoffInErp(int) stops locking materials editing. Used when a process is moved back out of the write-off status after the export already succeeded — the write-off is reversed in ERP (see ExportService.reverseWriteoffMovements(int)), and 1C-side reconciliation is out of ERP's scope. Does NOT commit — caller is responsible.
      Throws:
      SQLException
    • cancelPendingByProcessId

      public int cancelPendingByProcessId(int processId) throws SQLException
      Cancels what 1C has not confirmed — a queued send and one whose send failed — so the poller does not pick it up after the process has gone back to work. A confirmed one ('success', 'unposted') is not cancelled: it is reversed instead. A new entry is added on the next transition into the write-off status. Does NOT commit — caller is responsible. A send that failed on a timeout may still have reached 1C; reconciliation on the 1C side is out of ERP's scope, the same as for reversed.
      Returns:
      how many entries were cancelled.
      Throws:
      SQLException
    • delete

      public void delete(int id) throws SQLException
      Throws:
      SQLException
    • fromRs

      public static ExportQueue fromRs(ResultSet rs) throws SQLException
      Throws:
      SQLException