Към съдържанието

Новости

2.8.4 — 2026-09-30

heading.anchorLabel

Спрямо 2.8.3.

Комити (2)

heading.anchorLabel
  • d1a0040 fix: настройките за товарителницата се четат по store-а на поръчката
  • f8c5460 chore: post-release bump to 2.8.4

Бележки

heading.anchorLabel
  • Настройките за товарителницата се четат по store-а на поръчката. Диалогът ги четеше по store-а на поръчката, а ShipmentRequestBuilder само от Default. Масовото генериране от грида минава само през builder-а, така че настройка на ниво website или store view (платец, надбавка, подател, опции преди плащане, застраховка, разрешени услуги…) важеше в диалога, но не и там. Сега и двата пътя дават еднаква товарителница.
  • Scope-ът се задава при build() и getDefaultCodAmount() и се връща след това, защото builder-ът е споделен между поръчките при масовото генериране.

При деплой

heading.anchorLabel
  • ⚠️ Стойности на ниво website или store view под carriers/speedy/*, досега игнорирани при масовото генериране, започват да важат. Провери преди деплой:
    SELECT scope, scope_id, path, value FROM core_config_data
    WHERE path LIKE 'carriers/speedy/%' AND scope <> 'default';
    Празна (NULL) стойност на store ниво отменя наследената. На isd-bg.com такъв ред за accept_options на store 2 беше изтрит преди деплоя (30.09.2026).
  • Няма нови зависимости в конструктора, промени в схемата, шаблоните или статичните файлове: cache:flush.

2.8.3 — 2026-09-29

heading.anchorLabel

Спрямо 2.8.2.

Комити (2)

heading.anchorLabel
  • ced0c7c fix: извън България без опции преди плащане (ОПП)
  • 363a06c chore: post-release bump to 2.8.3

Бележки

heading.anchorLabel
  • Извън България товарителницата е без опции преди плащане. Speedy отказва пратката с „Детайли за ОПП: Опциите преди плащане/получаване не са позволени за държавата на получателя“ (поръчка до Гърция, isd-bg.com, 29.09.2026). Както при доставка до автомат, obpd отпада изцяло: и конфигурираният default (accept_options), и ръчно избраната в диалога опция.
  • Диалогът за товарителница не предлага опция извън BG. В България нищо не се променя.
  • ⚠️ Не е проверено с реална товарителница до чужбина (създаване и отказ).

При деплой

heading.anchorLabel
  • Няма нови зависимости в конструктора, промени в схемата, шаблоните или статичните файлове: cache:flush.

2.8.2 — 2026-09-29

heading.anchorLabel

Спрямо 2.8.1.

Комити (2)

heading.anchorLabel
  • af0198f fix: извън България куриерът е за сметка на търговеца
  • 80ff7ef chore: post-release bump to 2.8.2

Бележки

heading.anchorLabel
  • Извън България куриерът е за сметка на търговеца. Speedy не позволява платец получател за международните услуги и отказва пратката с „Платец: Избраният платец не е позволен за избраната услуга“ (поръчка до Гърция, isd-bg.com, 29.09.2026). При адрес или офис извън BG RECIPIENT става SENDER, и от настройката, и от диалога. THIRD_PARTY не се пипа.
  • С платец подателя наложеният платеж е пълната сума на поръчката (стока + доставка + надбавка за наложен платеж), така че клиентът плаща доставката през наложения платеж.
  • Диалогът за товарителница предлага SENDER по същото правило. Нов публичен метод ShipmentRequestBuilder::isCrossBorder().
  • ⚠️ Не е проверено с реална товарителница до чужбина (създаване и отказ).

При деплой

heading.anchorLabel
  • Няма нови зависимости в конструктора, промени в схемата, шаблоните или статичните файлове: cache:flush.

2.8.1 — 2026-09-29

heading.anchorLabel

Спрямо 2.8.0.

Комити (2)

heading.anchorLabel
  • edaeb11 fix: адрес извън BG/RO се подава с addressLine1, не с addressNote
  • eba9a62 chore: post-release bump to 2.8.1

Бележки

heading.anchorLabel
  • Адрес извън България и Румъния се подава с addressLine1. Speedy води по номенклатура само BG и RO адресите. За всички останали държави иска адресни редове и без addressLine1 отказва пратката с „Получател Адрес 1: Изисква се адрес“ (поръчка до Гърция, isd-bg.com, 29.09.2026). Досега модулът пращаше улицата само в addressNote.
  • За BG/RO няма промяна: улицата остава в addressNote, защото Speedy губеше номера, когато сам разчита addressLine1.
  • Улица над 50 знака се пренася в addressLine2, като се реже между думи. Улицата, въведена ръчно в диалога за товарителница, минава по същия път.
  • ⚠️ Не е проверено с реална товарителница до чужбина (създаване и отказ). Лимитът от 50 знака е по документацията на Speedy.

При деплой

heading.anchorLabel
  • Няма нови зависимости в конструктора, промени в схемата, шаблоните или статичните файлове: cache:flush.

2.8.0 — 2026-09-26

heading.anchorLabel

Спрямо 2.7.0.

Комити (2)

heading.anchorLabel
  • 836125f Release 2.8.0
  • 59b6451 feat: при цени от таблица услугата за товарителницата се избира по дестинация

Бележки

heading.anchorLabel
  • Услугата за товарителница по дестинация при цени от таблица (custom_prices). Методът тогава е тип доставка (speedy_address), не услуга. Досега товарителницата взимаше винаги първата разрешена услуга, тоест 505 и за чужбина, и операторът я сменяше на ръка в диалога. Сега услугата е първата разрешена (по реда на allowed_methods), която Speedy връща от services/destination за получателя. Пример с allowed_methods = 505,202,302,…: Гърция и Румъния → 202 (CEE Economy), България → 505. Палетните услуги (412, 432, 442…) не се избират, докато са по-назад в реда.
  • Ако Speedy не отговори или няма съвпадение, остава първата разрешена, както досега. Услугата, избрана в диалога, и услугата в метода (speedy_505, при API цени) печелят и не питат services/destination.
  • Нов клас Service\DestinationServices. Праща само местоположението на получателя (държава, населено място, пощенски код или офис) и подателя (clientId/dropoffOfficeId).

При деплой

heading.anchorLabel
  • Конструктор: ShipmentRequestBuilder има нова зависимост (DestinationServices). Трябва setup:di:compile и изчистен generated/. Автоматичният сигнал отгоре не го хваща.
  • Няма промени в схемата, в шаблоните и в статичните файлове: cache:flush.

2.7.0 — 2026-09-25

heading.anchorLabel

Спрямо 2.6.1.

Внимание при деплой

heading.anchorLabel
  • Конструктор: сменена сигнатура на __construct — при деплоя се чисти generated/.
  • Зависимости: require в composer.json: webcode/module-carrier: ^2.10 → ^2.12.

Комити (2)

heading.anchorLabel
  • 933bf73 Release 2.7.0
  • 976f519 feat(admin): searchable sender office picker

Бележки

heading.anchorLabel
  • „Choose office“ в конфигурацията на куриера е поле с търсене (UI Select от Webcode_Carrier 2.12.0) вместо <select> с всички офиси: търсене по град, име, адрес или номер, подредба по град и име, етикет [номер] ГРАД — име, адрес.
  • Model\Config\Source\Office е изтрит — оттам идва сигналът „Конструктор“ горе; нов конструктор няма. Запазената стойност (office_id) не се променя.
  • Старият source model викаше живото API на Speedy при всяко отваряне на страницата с настройки.

При деплой

heading.anchorLabel
  • Изисква webcode/module-carrier ^2.12. Чисти generated/ и пусни setup:static-content:deploy за adminhtml (заради JS-а в Carrier).

2.6.1 — 2026-09-24

heading.anchorLabel

Спрямо 2.6.0.

Внимание при деплой

heading.anchorLabel
  • Конструктор: сменена сигнатура на __construct — при деплоя се чисти generated/.
  • Setup: data/schema patch — изпълнява се срещу жива база при setup:upgrade.

Комити (1)

heading.anchorLabel
  • 5275289 fix: записът на куриера се възстановява сам (RecurringData), patch-ът е идемпотентен

Бележки

heading.anchorLabel
  • Записът на куриера в webcode_carrier_entity се възстановява сам. Ако таблицата е празна, а отметката на AddSpeedyCarrierEntityPatch е останала в patch_list (модулът е бил изключван и таблицата е създадена наново), куриерът досега оставаше без запис, докато някой не махне отметката на ръка. Сега новият Setup\RecurringData създава липсващия запис при всеки setup:upgrade: неактивен, както и при първа инсталация.
  • AddSpeedyCarrierEntityPatch::apply() е идемпотентен. При махната отметка и съществуващ запис вече не гърми на уникалния code.

При деплой

heading.anchorLabel
  • Уточнение към автоматичните предупреждения: никоя съществуваща сигнатура не е сменена. __construct е на новия клас Setup\RecurringData. В production mode е нужен setup:di:compile заради новия клас.
  • Съществуващият data patch не се пуска наново. RecurringData при всеки setup:upgrade чете записа по code и създава нов само ако липсва. Съществуващ запис, вкл. is_active, не се пипа.

2.6.0 — 2026-09-19

heading.anchorLabel

Спрямо 2.5.4.

Внимание при деплой

heading.anchorLabel
  • Зависимости: require в composer.json: webcode/module-carrier: ^2.9.2 → ^2.10.

Комити (3)

heading.anchorLabel
  • 2380056 Release 2.6.0
  • 4ec04c5 chore(carrier-11): изисквай webcode/module-carrier ^2.10
  • 890b3f3 feat(carrier-11): отказ на товарителница при отказ на поръчка

Бележки

heading.anchorLabel

Модулът вече може да анулира товарителницата при отказ на поръчка.

Закача вече съществуващия ShippingLabel::delete() (shipment/cancel), който до момента нямаше нито един извикващ — тоест кодът стоеше, но никога не се изпълняваше.

Включва се от Магазини → Конфигурация → Webcode Solutions → Delivery Methods → Товарителници. Настройката е обща за всички куриери и е изключена по подразбиране — това издание не променя нищо от само себе си.

Отказ от куриера никога не блокира отказа на поръчката; причината влиза в коментарите на поръчката и в лога.

Внимание при деплой

heading.anchorLabel
  • Изисква webcode/module-carrier ^2.10 — констрейнтът е стегнат в това издание, защото модулът вече ползва LabelCancellationInterface, който идва с carrier 2.10.0. Деплой без него би дал фатал при зареждане на класа.
  • Нужен е cache:flush (заради новия observer и конфигурация в carrier 2.10.0).
  • Няма промени по схема и по static content.

Известен проблем

heading.anchorLabel

Не е минат реален отказ на жива товарителница при куриера (DoD т. 2–3) — покритието е unit. Първият жив отказ да се наблюдава.

2.5.4 — 2026-09-18

heading.anchorLabel

Спрямо 2.5.3.

Комити (1)

heading.anchorLabel
  • 2e01140 диалогът за товарителница: не сваляй избрания тип на „до адрес“

2.5.3 — 2026-09-17

heading.anchorLabel

fix(address): доставка до адрес вече резолва населеното място вместо да пада в обслужващия офис.

  • countryId се маппва от ISO кода на поръчката през CarrierCountryRepository (BG→100), не 0 (Speedy отхвърляше 0 → офис).
  • siteName се чисти от префикса “гр.”/“с.” (иначе location/site връщаше празен списък → офис).

Засягаше ВСЯКА Speedy доставка до адрес. Изисква module-carrier ^2.9.2.

2.5.2 — 2026-09-16

heading.anchorLabel

fix(address): улицата с номера отива в addressNote вместо addressLine1. Speedy печата адреса дословно, тъй че номерът винаги стига до куриера; рутиране по siteId + пощенски код. Поправя доставка до адрес без номер на товарителницата.

2.5.0 — къде принадлежи надбавката и какво пише в съдържанието — 2026-09-09

heading.anchorLabel

Изисква webcode/module-carrier ^2.9.0

heading.anchorLabel

resolveContents() и isSurchargePartOfDelivery() са нови в базата. Старият constraint (^2.8.1) допускаше 2.8.x и билдът щеше да пада с undefined method.

Cash-on-Delivery Surcharge (carriers/speedy/surcharge_scope)

  • Part of the delivery — по подразбиране. Клиентът дължи наложен платеж за стоката; доставката с надбавката ѝ се събира от куриера.
  • Part of the order — надбавката остава в сумата, за търговец, който иска разбивката на цената на доставка да се вижда.

Действа само при платец получателя — иначе няма плащане на гише, което да следва.

⚠️ Промяна в поведението. Магазин с Webcode_Surcharge и платец получателя ще започне да издава товарителници с по-нисък наложен платеж. За 000020909: 98.06 → 96.90.

Parcel Contents (carriers/speedy/contents_template) — какво декларира товарителницата като съдържание. {increment_id} става номерът на поръчката (Поръчка 000020909); празно оставя списъка с артикулите, както досега.

Решение, което си струва да се знае

heading.anchorLabel

Проверката е за изричното order, не за delivery, тъй че подразбиращото се живее в кода, а etc/config.xml само го документира. Обратното би направило сумата, която куриерът събира от клиента, зависима от това дали конфигът се е заредил.

2.4.2 — 2026-09-05

heading.anchorLabel

Поправено

heading.anchorLabel
  • Колоната Location в tracking popup-а вече не е празна. Carrier::getTrackingInfo() пълнеше deliverylocation от comment — свободен текст, който Speedy не връща за повечето операции, тъй че колоната излизаше празна практически винаги. Правилното поле е place — единственото в TrackedParcelOperation, което носи място (https://api.speedy.bg/v1/schema). Добавен регресионен тест.
  • bin/magento config:set carriers/speedy/sender вече работи. Групата в system.xml се казваше sender, колкото и пътят на полето client_id. Magento резолвира по структурен път и попадаше в ГРУПАТА вместо в поле, тъй че полето беше недостижимо от CLI — за deploy скриптове и за всяка настройка извън админ формата. В админа работеше, затова дефектът беше невидим. Групата е преименувана; и шестте полета носят изричен config_path, тъй че нито една съхранена стойност не се осиротява.

Тестове

heading.anchorLabel

Test/Unit: 58 теста, 165 assertions. PHPCS Magento2: 0 errors.

2.4.1 — 2026-08-31

heading.anchorLabel

Поправено

heading.anchorLabel
  • ActiveGuard четеше подателя от грешния config-leaf. Проверката „има ли попълнен подател“ гледаше не там, където полето пази стойността си, тъй че gate-ът при пускане в експлоатация съдеше по празно. Сега чете sender.

2.4.0 — 2026-08-28

heading.anchorLabel
  • Магазинът избира кой плаща доставката. Payer политиката е споделена с останалите куриери през module-carrier (вече изисква ^2.8) и се подава при заявка за товарителница; изборът стои и в диалога „Create Shipping Label“.
  • Полетата на подателя са задължителни при пускане в експлоатация. Нов Model/Config/Backend/ActiveGuard не дава Speedy да се включи с празен подател, вместо конфигурацията да мине и заявките да падат по-късно.
  • Вход в Speedy със запазените креденшъли от админ контролера, без повторно въвеждане.

2.3.2 — 2026-08-25

heading.anchorLabel

Register carriers/speedy/api_url as a hidden system.xml field, so the API base URL is manageable per environment via bin/magento config:set / env.php (no merchant UI; default stays in config.xml).

2.3.1 — 2026-08-21

heading.anchorLabel
  • Етикетът на метода в checkout вече показва само бранда и типа доставка (напр. „Speedy - До офис на куриер“), без името на услугата от API-то („СТАНДАРТ 24 ЧАСА“). Клиентите четяха услугата като срок за доставка и си търсеха пратката „след 24 часа“.
  • Махната неизползваната вече зависимост CarrierService от Model\Carrier.

Инвариантът „carrierTitle = конфигурираното заглавие“ живее в Webcode_Carrier (2.7.1) и важи за всички куриери; тук е само cleanup-ът.

2.2.4 — 2026-08-19

heading.anchorLabel

Поправено

heading.anchorLabel

Speedy отхвърляше товарителниците за частни лица.

Получател Лице за контакт: Не се очаква име на контакт

Второ затягане на валидацията за един ден. Сутринта API-то поиска име на получателя (2.2.3 добави clientName), а следобед започна да отхвърля contactName при privatePerson — частното лице Е получателят, лице за контакт не се очаква.

Затова името се подава единствено като clientName. Това удовлетворява и двете правила.

sender.contactName остава непроменен — той е за подателя и е друго поле.

Как се разпозна

heading.anchorLabel

Мерено на bilki.bg 19.08.2026, при непроменен код и payload:

6 успешни товарителници 14:53 … 15:21
2 провала 15:25, 15:28

Разграничителят е времето, не поръчката и не офисът — проверено, че трите payload-а са структурно еднакви.

Тестове

heading.anchorLabel

testRecipientCarriesClientNameAlongsideContactName е преработен: clientName присъства, contactName отсъства (assertArrayNotHasKey).

2.2.3 — 2026-08-19

heading.anchorLabel

Поправено

heading.anchorLabel

Теглото на пратката идва от поръчката, не от конфигурацията

heading.anchorLabel

buildContent() подаваше default_weight винаги, когато няма override — тоест при масово генериране и при автоматичното създаване. Реалното тегло на поръчката се игнорираше и куриерът дотаксуваше. Дефектът е невидим: нищо не гърми, нищо не влиза в лог, товарителницата просто тръгва лека.

Мерено на bilki.bg, поръчки със Speedy за 30 дни: средно 1.41 кг, максимум 44.13 кг, а 764 от 1756 (43%) над 1 кг при default_weight = 1.

Редът става override → тегло на поръчката → default_weight, по модела на BoxNow — единственият от петте куриера, който го правеше правилно. Същата поправка влезе и в Econt 2.3.1, Evropat и PostOne.

Идентичност на получателя — clientName

heading.anchorLabel

Влезе с 2.2.2 (!23) и се пренася тук: Speedy отказваше всяка товарителница с „Получател: Необходимо е да бъде подадено или id или име на получател“, след като на 19.08.2026 затегна валидацията. contactName е лице за контакт и не удовлетворява идентичността.

Кой трябва да я вземе

heading.anchorLabel

Всяка инсталация на 2.x — при 1.0.x ShippingLabel::create() няма извикващ, тоест товарителници оттам не се генерират.

2.2.2 — 2026-08-19

heading.anchorLabel

Поправено

heading.anchorLabel

Speedy отказваше всяка товарителница. От 19.08.2026 API-то вали с

Получател: Необходимо е да бъде подадено или id или име на получател

при непроменен наш код. По Speedy ClientDTO идентичността на получателя е clientId или clientName; contactName е лице за контакт и вече не я удовлетворява. buildRecipient() сега подава и двете полета с една и съща стойност, с непроменения fallback към firstname + lastname.

Доказано срещу живото API: същата поръчка отказана без полето и приета с него.

Засяга всяка инсталация на 2.x — при 1.0.x ShippingLabel::create() няма извикващ, тоест товарителници оттам не са се генерирали.

2.2.0 — 2026-07-28

heading.anchorLabel

Populate webcode_directory_city.region_id during Speedy city taxonomy sync via Webcode Carrier RegionResolver, on create and as self-heal for existing rows. Requires carrier ^2.6.

2.1.0 — 2026-07-28

heading.anchorLabel

Delivery Methods config cleanup:

  • API base URL default живее в etc/config.xml (carriers/speedy/api_url), не като PHP const; override през config:set / env.php / DB.
  • Креденшълите (username/password) вече не са required за Save на секцията; валидацията е бутонът Login & Configure.

2.0.1 — 2026-07-24

heading.anchorLabel

Speedy checkout place-order integration test matrix: 2 pricing modes x guest/customer x address/office/aps + COD + rival-carrier + estimate-preserves-choice regression. SpeedyApiStub (no live API).