Ter várias visualizações de loja compartilhando o mesmo intervalo de número increment_id de pedido

13

O Magento pode ser configurado de forma que várias visualizações de loja do mesmo site possam compartilhar o mesmoincrement_id intervalo de números de pedidos ? E se sim, como?

Por exemplo, com uma configuração de armazenamento múltiplo como esta em core_store:

store_id        code    website_id    group_id
       0       admin             0           0
       1       alpha             1           1
       2       bravo             2           2
       3     charlie             2           2

Agora, uma nova visualização da loja deltaé adicionada:

store_id        code    website_id    group_id
       4       delta             1           1

Supondo que alphao último ID de incremento do pedido atualmente seja 1000123, como obter:

next sell    order number
    alpha         1000124
    delta         1000125
    delta         1000126
    alpha         1000127

A mesma pergunta vale para várias visualizações da loja que compartilham o mesmo increment_idintervalo de números da fatura e / ou compartilham o mesmo intervalo de increment_idnúmeros do creditmemo .

O Magento suporta esse recurso pronto para uso?

Jürgen Thelen
fonte
Com a orientação de @ alessandro-ronchi, implementei a solução assim. gist.github.com/mblarsen/012dce6f55ad5d442f41e9157e74530e funciona muito bem para mim.
Michael

Respostas:

5

Eu imagino que isso seria bastante difícil. Os IDs de incremento são armazenados na eav_entity_storetabela e, surpreendentemente, cada loja possui sua própria entrada, que é atualizada quando um pedido (e cotação, fatura etc.) é criado. Para que todas as lojas usem o mesmo incrementador, seria necessário reescrever essa lógica para que ela usasse a mesma linha no banco de dados. O impacto que isso pode ter em outras áreas do site é outra coisa que precisaria ser considerada.

Richard Cleverley
fonte
Eu concordo com o Richard.
Sylvain Rayé 30/01
Você provavelmente está certo, mas executar este código e todos os meus faturas seguem uma mesma sequência de númerosMage::getModel('eav/entity_type')->loadByCode('invoice')->setIncrementPerStore(false)->save()
Jay Ghosh
3

Você pode substituir o modelo de incremento de pedidos, remessas, faturas e notas de crédito reescrevendo a classe "eav / entity_increment_numeric", fornecendo lógica personalizada em um modelo seu.

Dê uma olhada nas classes ancestrais (Mage_Eav_Model_Entity_Increment_Numeric e Mage_Eav_Model_Entity_Increment_Abstract) para entender como fornecer sua própria lógica.

Você pode diferenciar a lógica entre diferentes entidades, verificando o parâmetro $ entityTypeCode da função getNextId () que você substituirá.

Outra maneira (mais invasiva) é especificar um modelo de incremento diferente para cada tipo de entidade, substituindo (via script de instalação) o valor da coluna "increment_model" da tabela "eav_entity_type". Pessoalmente, prefiro a solução "reescrever" mencionada acima.

Preste atenção: os IDs de incremento têm uma restrição de exclusividade nas versões mais recentes do Magento, portanto você não pode armazenar o mesmo ID de incremento para duas entidades diferentes do mesmo tipo. Em outras palavras, você não pode ter duas faturas diferentes com o mesmo ID de incremento.

Espero que ajude.

Alessandro Ronchi
fonte
Olhei para isso, mas eu sou incapaz de encontrar getLastId()em Mage_Eav_Model_Entity_Increment_Numericou em qualquer outra classe ou interface na hierarquia. Btw, esta deve ser a resposta aceita.
Michael
UPDATE: Só percebi que é um conjunto de propriedades na Varien_ObjectdeMage_Eav_Model_Entity_Type
Michael
2

Ao cavar mais fundo, percebi que isso eav_entity_type.increment_per_storepode ser útil.

Isto é. Mas apenas no caso, quando você deseja que todas as visualizações da loja (globalmente, não importa em qual site elas estejam definidas) da sua instalação do Magento compartilhem o mesmo increment_idintervalo de números de pedidos .

Isso não resolve meu problema específico, mas talvez seja útil para outros, então aqui vamos nós:

Para ativar o compartilhamento global de seus números de pedidos, defina eav_entity_type.increment_per_storea entidade do pedido como 0,

Isso leva ao Mage_Eav_Model_Entity_Type::fetchNewIncrementId()uso store_id = 0ao carregar o eav_entity_storeregistro da entidade do pedido, independentemente da exibição da loja à qual realmente pertence.

Se esse registro não existir, o Magento criará um, usando store_ide increment_prefixde 0.

public function fetchNewIncrementId($storeId = null)
{
    if (!$this->getIncrementModel()) {
        return false;
    }

    if (!$this->getIncrementPerStore() || ($storeId === null)) {
        /**
         * store_id null we can have for entity from removed store
         */
        $storeId = 0;
    }

    // Start transaction to run SELECT ... FOR UPDATE
    $this->_getResource()->beginTransaction();

    $entityStoreConfig = Mage::getModel('eav/entity_store')
        ->loadByEntityStore($this->getId(), $storeId);

    if (!$entityStoreConfig->getId()) {
        $entityStoreConfig
            ->setEntityTypeId($this->getId())
            ->setStoreId($storeId)
            ->setIncrementPrefix($storeId)
            ->save();
    }

    $incrementInstance = Mage::getModel($this->getIncrementModel())
        ->setPrefix($entityStoreConfig->getIncrementPrefix())
        ->setPadLength($this->getIncrementPadLength())
        ->setPadChar($this->getIncrementPadChar())
        ->setLastId($entityStoreConfig->getIncrementLastId())
        ->setEntityTypeId($entityStoreConfig->getEntityTypeId())
        ->setStoreId($entityStoreConfig->getStoreId());

    /**
     * do read lock on eav/entity_store to solve potential timing issues
     * (most probably already done by beginTransaction of entity save)
     */
    $incrementId = $incrementInstance->getNextId();
    $entityStoreConfig->setIncrementLastId($incrementId);
    $entityStoreConfig->save();

    // Commit increment_last_id changes
    $this->_getResource()->commit();

    return $incrementId;
}

Isso deve funcionar para qualquer tipo de entidade usando o eav/entity_increment_numericmodelo, como order, invoice, shipmente creditmemo.

Esteja ciente, porém, de que ainda não consegui encontrar nenhuma documentação oficial increment_per_store. E que não há opção no back-end do Magento, permitindo que você configure isso.

Isso pode ou não significar que não se pensa que seja usado oficialmente.

Use por sua conta e risco. Se suas mudanças causam estragos, não me culpe. Você foi avisado ^^

Jürgen Thelen
fonte
1

Não é suportado pronto para uso. Eu também queria fazer isso uma vez para ter uma segunda visualização de armazenamento para um teste A / B compartilhar o mesmo increment_id da loja original.

Tentei combinar esses dois números da maneira mais simples quando checkout_submit_all_afteré demitido, mas me senti muito desconfortável com isso, então deixei cair. Eu acho que com mais visualizações de loja e muito tráfego, isso pode resultar em uma verdadeira bagunça, então você precisa se aprofundar na lógica do Magentos.

mnp
fonte
0

Solução:

Ter um intervalo de pedidos / fatura / creditmemo diferente etc ... é bastante bom para diferentes países, o que geralmente significa em nível de grupo de lojas.

Mas ter intervalos de números diferentes no nível da visualização da loja é uma coisa ruim se você usar as visualizações da loja para idiomas diferentes, o que pode ser feito em 90% de todos os casos.

Felizmente, não é tão difícil como proposto neste tópico:

O que vamos fazer é buscar o ID de visualização de loja padrão em vez de usar o ID de visualização de loja com o qual o método é chamado . Estamos fazendo isso resolvendo o grupo de lojas da visualização atual da loja e buscando seu ID de visualização padrão. Então, cada visualização de loja de um grupo de lojas específico usa o mesmo formato de intervalo numérico (o da visualização de loja padrão).

Crie esta classe:

class Funky_Module_Model_Entity_Type extends Mage_Eav_Model_Entity_Type
{
    /**
     * Retreive new incrementId
     *
     * @param int $storeId
     * @return string
     * @throws Exception
     */
    public function fetchNewIncrementId($storeId = null)
    {
        if (!$this->getIncrementModel()) {
            return false;
        }

        if (!$this->getIncrementPerStore() || ($storeId === null)) {
            /**
             * store_id null we can have for entity from removed store
             */
            $storeId = 0;
        }

        //FIX START:
        $groupId = Mage::getModel('core/store')->load($storeId)->getGroupId();
        $group =  Mage::getModel('core/store_group')->load($groupId);
        $storeId = $group->getDefaultStoreId();
        //FIX END:

        // Start transaction to run SELECT ... FOR UPDATE
        $this->_getResource()->beginTransaction();

        try {

            $entityStoreConfig = Mage::getModel('eav/entity_store')
                ->loadByEntityStore($this->getId(), $storeId);

            if (!$entityStoreConfig->getId()) {
                $entityStoreConfig
                    ->setEntityTypeId($this->getId())
                    ->setStoreId($storeId)
                    ->setIncrementPrefix($storeId)
                    ->save();
            }

            $incrementInstance = Mage::getModel($this->getIncrementModel())
                ->setPrefix($entityStoreConfig->getIncrementPrefix())
                ->setPadLength($this->getIncrementPadLength())
                ->setPadChar($this->getIncrementPadChar())
                ->setLastId($entityStoreConfig->getIncrementLastId())
                ->setEntityTypeId($entityStoreConfig->getEntityTypeId())
                ->setStoreId($entityStoreConfig->getStoreId());

            /**
             * do read lock on eav/entity_store to solve potential timing issues
             * (most probably already done by beginTransaction of entity save)
             */
            $incrementId = $incrementInstance->getNextId();
            $entityStoreConfig->setIncrementLastId($incrementId);
            $entityStoreConfig->save();

            // Commit increment_last_id changes
            $this->_getResource()->commit();
        } catch (Exception $e) {
            $this->_getResource()->rollBack();
            throw $e;
        }

        return $incrementId;
    }

}

Adicione esta reescrita ao config.xml do seu módulo:

<global>
   <models>
            <eav>
                <rewrite>
                     <entity_type>Gigaset_Core_Model_Entity_Type</entity_type>
                </rewrite>
            </eav> 
    ...

Se você tem um jeito melhor, sem precisar reescrever, espalhe o conhecimento. Diverta-se. Não corte o núcleo.

Michael Leiss
fonte