Полноценно редактируются черновики

Добавляются фасовки как в черновике, так и в обучении
Исправил внешний вид
This commit is contained in:
2025-12-17 22:00:21 +03:00
parent e2df2350f7
commit c8aab42e8e
24 changed files with 1313 additions and 433 deletions

View File

@@ -38,6 +38,8 @@ type ClientI interface {
FetchInvoices(from, to time.Time) ([]invoices.Invoice, error)
FetchStoreOperations(presetID string, from, to time.Time) ([]StoreReportItemXML, error)
CreateIncomingInvoice(inv invoices.Invoice) (string, error)
GetProductByID(id uuid.UUID) (*ProductFullDTO, error)
UpdateProduct(product ProductFullDTO) (*ProductFullDTO, error)
}
type Client struct {
@@ -571,14 +573,20 @@ func (c *Client) CreateIncomingInvoice(inv invoices.Invoice) (string, error) {
price, _ := item.Price.Float64()
sum, _ := item.Sum.Float64()
reqDTO.ItemsWrapper.Items = append(reqDTO.ItemsWrapper.Items, IncomingInvoiceImportItemXML{
xmlItem := IncomingInvoiceImportItemXML{
ProductID: item.ProductID.String(),
Amount: amount,
Price: price,
Sum: sum,
Num: i + 1,
Store: inv.DefaultStoreID.String(),
})
}
if item.ContainerID != nil && *item.ContainerID != uuid.Nil {
xmlItem.ContainerId = item.ContainerID.String()
}
reqDTO.ItemsWrapper.Items = append(reqDTO.ItemsWrapper.Items, xmlItem)
}
// 2. Маршалинг в XML
@@ -613,7 +621,6 @@ func (c *Client) CreateIncomingInvoice(inv invoices.Invoice) (string, error) {
zap.String("url", fullURL),
zap.String("body_payload", string(xmlPayload)),
)
// ----------------------------------------
// 5. Отправка
req, err := http.NewRequest("POST", fullURL, bytes.NewReader(xmlPayload))
@@ -659,3 +666,92 @@ func (c *Client) CreateIncomingInvoice(inv invoices.Invoice) (string, error) {
return result.DocumentNumber, nil
}
// GetProductByID получает полную структуру товара по ID (через /list?ids=...)
func (c *Client) GetProductByID(id uuid.UUID) (*ProductFullDTO, error) {
// Параметр ids должен быть списком. iiko ожидает ids=UUID
params := map[string]string{
"ids": id.String(),
"includeDeleted": "false",
}
resp, err := c.doRequest("GET", "/resto/api/v2/entities/products/list", params)
if err != nil {
return nil, fmt.Errorf("request error: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("rms error code %d", resp.StatusCode)
}
// Ответ - это массив товаров
var products []ProductFullDTO
if err := json.NewDecoder(resp.Body).Decode(&products); err != nil {
return nil, fmt.Errorf("json decode error: %w", err)
}
if len(products) == 0 {
return nil, fmt.Errorf("product not found in rms")
}
return &products[0], nil
}
// UpdateProduct отправляет полную структуру товара на обновление (/update)
func (c *Client) UpdateProduct(product ProductFullDTO) (*ProductFullDTO, error) {
// Маршалим тело
bodyBytes, err := json.Marshal(product)
if err != nil {
return nil, fmt.Errorf("json marshal error: %w", err)
}
// Используем doRequestPost (надо реализовать или вручную, т.к. doRequest у нас GET-ориентирован в текущем коде был прост)
// Расширим логику doRequest или напишем тут, т.к. это POST с JSON body
if err := c.ensureToken(); err != nil {
return nil, err
}
c.mu.RLock()
token := c.token
c.mu.RUnlock()
endpoint := c.baseURL + "/resto/api/v2/entities/products/update?key=" + token
req, err := http.NewRequest("POST", endpoint, bytes.NewReader(bodyBytes))
if err != nil {
return nil, err
}
req.Header.Set("Content-Type", "application/json")
resp, err := c.httpClient.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
respBody, _ := io.ReadAll(resp.Body)
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("update failed (code %d): %s", resp.StatusCode, string(respBody))
}
var result UpdateEntityResponse
if err := json.Unmarshal(respBody, &result); err != nil {
return nil, fmt.Errorf("response unmarshal error: %w", err)
}
if result.Result != "SUCCESS" {
// Собираем ошибки
errMsg := "rms update error: "
for _, e := range result.Errors {
errMsg += fmt.Sprintf("[%s] %s; ", e.Code, e.Value)
}
return nil, fmt.Errorf(errMsg)
}
if result.Response == nil {
return nil, fmt.Errorf("empty response from rms after update")
}
return result.Response, nil
}