редактирование и удаление сопоставлений

список накладных с позициями
This commit is contained in:
2025-12-29 10:46:05 +03:00
parent c2d382cb6a
commit 310a64e3ba
30 changed files with 1250 additions and 8173 deletions

View File

@@ -152,7 +152,7 @@ func (s *Service) DeleteDraft(id uuid.UUID) (string, error) {
return draft.Status, nil
}
func (s *Service) UpdateDraftHeader(id uuid.UUID, storeID *uuid.UUID, supplierID *uuid.UUID, date time.Time, comment string) error {
func (s *Service) UpdateDraftHeader(id uuid.UUID, storeID *uuid.UUID, supplierID *uuid.UUID, date time.Time, comment string, incomingDocNum string) error {
draft, err := s.draftRepo.GetByID(id)
if err != nil {
return err
@@ -164,6 +164,7 @@ func (s *Service) UpdateDraftHeader(id uuid.UUID, storeID *uuid.UUID, supplierID
draft.SupplierID = supplierID
draft.DateIncoming = &date
draft.Comment = comment
draft.IncomingDocumentNumber = incomingDocNum
return s.draftRepo.Update(draft)
}
@@ -270,14 +271,15 @@ func (s *Service) CommitDraft(draftID, userID uuid.UUID) (string, error) {
// 4. Сборка Invoice
inv := invoices.Invoice{
ID: uuid.Nil,
DocumentNumber: draft.DocumentNumber,
DateIncoming: *draft.DateIncoming,
SupplierID: *draft.SupplierID,
DefaultStoreID: *draft.StoreID,
Status: targetStatus,
Comment: draft.Comment,
Items: make([]invoices.InvoiceItem, 0, len(draft.Items)),
ID: uuid.Nil,
DocumentNumber: draft.DocumentNumber,
DateIncoming: *draft.DateIncoming,
SupplierID: *draft.SupplierID,
DefaultStoreID: *draft.StoreID,
Status: targetStatus,
Comment: draft.Comment,
IncomingDocumentNumber: draft.IncomingDocumentNumber,
Items: make([]invoices.InvoiceItem, 0, len(draft.Items)),
}
for _, dItem := range draft.Items {
@@ -338,7 +340,25 @@ func (s *Service) CommitDraft(draftID, userID uuid.UUID) (string, error) {
return "", err
}
// 6. Обновление статуса черновика
// 6. Поиск UUID созданной накладной
invoices, err := client.FetchInvoices(*draft.DateIncoming, *draft.DateIncoming)
if err != nil {
logger.Log.Warn("Не удалось получить список накладных для поиска UUID", zap.Error(err), zap.Time("date", *draft.DateIncoming))
} else {
found := false
for _, invoice := range invoices {
if invoice.DocumentNumber == docNum {
draft.RMSInvoiceID = &invoice.ID
found = true
break
}
}
if !found {
logger.Log.Warn("UUID созданной накладной не найден", zap.String("document_number", docNum), zap.Time("date", *draft.DateIncoming))
}
}
// 7. Обновление статуса черновика
draft.Status = drafts.StatusCompleted
s.draftRepo.Update(draft)
@@ -471,6 +491,8 @@ type UnifiedInvoiceDTO struct {
ItemsCount int `json:"items_count"`
CreatedAt time.Time `json:"created_at"`
IsAppCreated bool `json:"is_app_created"`
PhotoURL string `json:"photo_url"`
ItemsPreview string `json:"items_preview"`
}
func (s *Service) GetUnifiedList(userID uuid.UUID, from, to time.Time) ([]UnifiedInvoiceDTO, error) {
@@ -491,6 +513,12 @@ func (s *Service) GetUnifiedList(userID uuid.UUID, from, to time.Time) ([]Unifie
return nil, err
}
// 3. Получаем мапу rms_invoice_id -> sender_photo_url
photoMap, err := s.draftRepo.GetRMSInvoiceIDToPhotoURLMap(server.ID)
if err != nil {
return nil, err
}
result := make([]UnifiedInvoiceDTO, 0, len(draftsList)+len(invoicesList))
// Маппим черновики
@@ -510,6 +538,19 @@ func (s *Service) GetUnifiedList(userID uuid.UUID, from, to time.Time) ([]Unifie
date = *d.DateIncoming
}
// Формируем ItemsPreview для черновиков
var itemsPreview string
if len(d.Items) > 0 {
names := make([]string, 0, 3)
for i, it := range d.Items {
if i >= 3 {
break
}
names = append(names, it.RawName)
}
itemsPreview = strings.Join(names, ", ")
}
result = append(result, UnifiedInvoiceDTO{
ID: d.ID,
Type: "DRAFT",
@@ -522,6 +563,8 @@ func (s *Service) GetUnifiedList(userID uuid.UUID, from, to time.Time) ([]Unifie
ItemsCount: len(d.Items),
CreatedAt: d.CreatedAt,
IsAppCreated: true,
PhotoURL: d.SenderPhotoURL,
ItemsPreview: itemsPreview,
})
}
@@ -533,7 +576,29 @@ func (s *Service) GetUnifiedList(userID uuid.UUID, from, to time.Time) ([]Unifie
}
val, _ := sum.Float64()
isOurs := strings.Contains(strings.ToUpper(inv.Comment), "RMSER")
// Определяем IsAppCreated и PhotoURL через мапу
isAppCreated := false
photoURL := ""
if url, exists := photoMap[inv.ID]; exists {
isAppCreated = true
photoURL = url
}
// Формируем ItemsPreview для синхронизированных накладных
var itemsPreview string
if len(inv.Items) > 0 {
names := make([]string, 0, 3)
for i, it := range inv.Items {
if i >= 3 {
break
}
// Предполагаем, что Product подгружен, иначе нужно добавить Preload
if it.Product.Name != "" {
names = append(names, it.Product.Name)
}
}
itemsPreview = strings.Join(names, ", ")
}
result = append(result, UnifiedInvoiceDTO{
ID: inv.ID,
@@ -545,7 +610,9 @@ func (s *Service) GetUnifiedList(userID uuid.UUID, from, to time.Time) ([]Unifie
TotalSum: val,
ItemsCount: len(inv.Items),
CreatedAt: inv.CreatedAt,
IsAppCreated: isOurs,
IsAppCreated: isAppCreated,
PhotoURL: photoURL,
ItemsPreview: itemsPreview,
})
}
@@ -553,3 +620,34 @@ func (s *Service) GetUnifiedList(userID uuid.UUID, from, to time.Time) ([]Unifie
// (Здесь можно добавить библиотеку sort или оставить как есть, если БД уже отсортировала части)
return result, nil
}
func (s *Service) GetInvoiceDetails(invoiceID, userID uuid.UUID) (*invoices.Invoice, string, error) {
// Получить накладную
inv, err := s.invoiceRepo.GetByID(invoiceID)
if err != nil {
return nil, "", err
}
// Проверить, что пользователь имеет доступ к серверу накладной
server, err := s.accountRepo.GetActiveServer(userID)
if err != nil || server == nil {
return nil, "", errors.New("нет активного сервера")
}
if inv.RMSServerID != server.ID {
return nil, "", errors.New("накладная не принадлежит активному серверу")
}
// Попытаться найти черновик по rms_invoice_id
draft, err := s.draftRepo.GetByRMSInvoiceID(invoiceID)
if err != nil {
return nil, "", err
}
photoURL := ""
if draft != nil {
photoURL = draft.SenderPhotoURL
}
return inv, photoURL, nil
}