Caisse électronique avec GoogleSheet

By | 13 août 2019 |

Dans cet article, je décris comment j’ai créé une caisse électronique avec GoogleSheet.

Aperçu de ma caisse électronique avec GoogleSheet

Avant d’aller plus loin et ceci afin d’éviter que vous ne perdiez votre temps à lire tout l’article pour arriver à la conclusion que ce n’est pas ce à quoi vous vous attendiez, voici un aperçu du fonctionnement de ma caisse électronique avec GoogleSheet.

Demo Caisse électronique avec GoogleSheet

Buts de ma caisse électronique avec GoogleSheet

J’ai créé cette GoogleSheet afin de répondre à un besoin spécifique, comment améliorer la gestion de la caisse (pour les commandes de boissons et nourritures) lors de la Fancy Fair de l’école.

Pour les « Fancy Fair » ou autres fêtes des clubs sportifs, il y a deux écoles, soit l’on paie directement au barman ou serveur, soit l’on passe par une caisse centrale afin de commander des tickets avant de se rendre au bar.

Dans ma situation, les commandes se passent à une caisse centrale via un système de cartes (10 cases) et cases, chaque article étant associé à une nombre de cases (par exemple: 1 Coca = 3 cases, une bière = 4 cases).
Les clients peuvent commander au détails (par exemple 3 Coca + 2 Jupiler + 5 Glaces) ou par carte.
Le prix des cases et donc des cartes étant fixé (cette année à 0,60€)

Cette GoogleSheet a pour but de soulager le responsable de la caisse.
Je vous entends ricaner d’ici, vous avez besoin d’une sheet excel pour ça, c’est de l’arithmétique élémentaire..
Et ben oui car dans la pratique cette personne

  • doit connaître le prix de chaque « article »,
    ce qui représente le 1er risque d’erreur, si elle vend le Coca à 1,50€ au lieu de 1,80€..
  • doit pouvoir calculer le total,
    ça semble anodin mais sous la pression devant une longue file, les clients qui changent la commande plusieurs fois, en fin de soirée ou après quelques bières, quelques cafouillages sont possibles.
  • doit pouvoir rendre l’argent,
    on a tous déjà reçu en retour plus que ce que l’on a donné au magasin, si votre caissier n’est pas une personne habituée à manier l’argent, le risque d’erreur est important

Avantages de ma caisse électronique avec GoogleSheet

  • La sheet se charge de calculer le montant à payer pour chaque commande,
    ceci évite au caissier de devoir connaître le prix de tous les produits et les éventuelles erreurs d’arithmétique.
  • La sheet se charge de calculer le montant à rendre,
    ceci évite toute erreur dans les calculs
  • La sheet fournit un inventaire des ventes,
    ce qui permet d’éviter les gaspillages et de mieux cibler les articles qui se vendent bien ou pas, voir même de diminuer le prix de certains articles pour encourager les ventes.
  • La sheet calcule en temps réel le montant dans la caisse
  • La sheet offre plus de transparence,
    avec un deuxième écran, vous pouvez afficher le détail de la commande et le total à votre client.

Inconvénients de ma caisse électronique avec GoogleSheet

  • il faut être connecté à Internet,
    la fonctionnalité ne fonctionne pas offline.
  • il faut un ordinateur à la caisse,
    le clic sur les cellules ne fonctionne pas sur les smartphones ou tablettes, pas testé sur les ordinateurs avec écran tactile.
  • il faut être un minimum familier avec les ordinateurs,
    savoir se servir d’une souris est suffisant 😉

Contraintes de ma caisse électronique avec GoogleSheet

  • Gratuit
    Comme ce projet est réalisé pour couvrir une « Fancy Fair », cette caisse enregistreuse se doit d’être gratuite
  • Facile à utiliser
    Le caissier ne doit pas être informaticien,
    il doit juste savoir cliquer sur les cellules correspondantes aux produits commandés
  • Facile à mettre à jour
    La mise à jour des prix ou des produits doit être possible par tout un chacun

Fonctionnement de ma caisse électronique avec GoogleSheet

Grâce à Google Apps Script, la google sheet peut être enrichie de fonctionnalités, un peu comme vous ajoutez des fonctionnalités via des macros dans Microsoft Excel.

Dans notre cas, lorsque l’on va cliquer sur certaines cellules, qui nous permettra tantôt d’ajouter l’article à une commande, tantôt de valider la commande et de mettre à jour les stocks.

Oui, oui… Je sais j’ai écris qu’il faut pas être informaticien pour s’en servir ou mettre à jour, je vous rassure de suite, vous ne devez pas être programmeur, vos connaissances peuvent s’arrêter à un copier/coller.

Regardons maintenant dans le détail.

Liste des articles, prix et inventaires

La première sheet de notre classeur Google sert justement à nous donner la liste des articles, leur prix respectif (ainsi que le nombre de cases).
Lorsqu’une commande est validée, c’est à dire payée, le nombre d’articles vendus (colonne ‘Sell’) ainsi que le total dans la caisse est mis à jour.

Caisse électronique avec GoogleSheet  - liste des produits
Caisse électronique avec GoogleSheet – liste des produits

La colonne ‘Available’, pour le nombre d’articles disponible est présente mais pas utilisée dans cette version, peut être dans une prochaine monture, le but étant d’éviter de vendre une article épuisé.
Vous l’aurez compris, il suffit de mettre à jour cette sheet avec les nouveaux articles et/ou prix d’années en années afin de se servir de la sheet pour les événements futurs.

Commandes et total

La deuxième sheet est celle utilisée par le « caissier » le jour de l’événement.
Elle se compose de deux parties

Caisse électronique avec GoogleSheet  - main sheet
Caisse électronique avec GoogleSheet – main sheet
  • A gauche,
    avec les différents boutons sur lesquels le caissier devra cliquer selon les articles commandés
  • A droite
    Le détail de la commande

Lorsque le caissier clique sur un bouton de la partie de gauche, l’article est ajouté à la partie de droite, les totaux (en € et en nombre de cases) sont calculés.
Pour ajouter plusieurs fois le même article, il suffit de cliquer plusieurs fois sur celui-ci, le compteur dans la colonne « Quantité » de la partie de droite devrait s’incrémenté; il est également possible de mettre à jour la quantité directement dans cette colonne, mais autant que possible je préfère éviter le recours à la saisie manuelle.

Combien rendre ?

Dans le bas de la partie gauche,
intéressons-nous aux cellules « Reçu » et « A rendre »

Caisse électronique avec GoogleSheet  - Reçu et A rendre
Caisse électronique avec GoogleSheet – Reçu et A rendre

Lorsque le total de la commande est calculé, s’il en éprouve le besoin, le caissier peut entrer le montant reçu et la sheet va lui calculer le montant à rendre.
Par exemple, si le montant de la commande est de 3,60€ et que le client vous tend un billet de 5€, il faut entrer 5 dans la cellule « Reçu »

Caisse électronique avec GoogleSheet  - Exemple A rendre
Caisse électronique avec GoogleSheet – Exemple A rendre

Et la sheet vous informe que vous devez rendre 1,40€ au client.

Boutons ?

Si vous êtes habitué à Google Sheet, vous vous demandez probablement comment on ajoute des boutons ?
C’est là qu’il y a un subterfuge, ce ne sont pas des boutons mais des images, auxquelles vous assigner un script. Pour ajouter les images rendez-vous dans le menu Insertion >> Images

Assigner script à une image

Dans mon exemple, j’ai choisis des images transparentes que je redimensionne à la taille de ma cellule, celle-ci laisse donc transparaître le texte et la couleur de la cellule.
(J’ai également choisi un code couleur qui rappelle le prix de chaque article). Mais si vous préferez, vous pouvez utiliser les logos des articles que vous vendez (Coca Cola, Jupiler, ..), pour donner une allure plus professionnelle, après reste à savoir si vous pouvez utiliser ces images…

Et techniquement ?

Comme vous vous en doutez, il y a un peu de code pour arriver à cela, décomposons les différentes fonctionnalités de ma caisse électronique avec GoogleSheet.

Lien entre bouton et article

Lorsque vous assigner un script à une image, vous liez cette image à une fonction, dans mon cas le code de ces fonctions est très simple, prenons deux exemples; pour l’eau (plate) et le Coca Zero

Assigner un script à une image
function eau() {
  var lv_product = 'Eau'
  product(lv_product)
}

function coca_zero() {
  var lv_product = 'Coca Zero'
  product(lv_product)
}

Les différences entre les deux fonctions sont leur nom et la variable « lv_product« , la valeur de cette variable (lv_product) doit correspondre avec le nom d’un article de la première sheet, c’est grâce à ce nom que l’on retrouve la bonne ligne et donc le prix de l’article.

Il va sans dire que dans mon scenario, l’image étant transparente, le script auquel j’assigne l’image est directement lié au texte de la cellule sous l’image

Maintenance

Si vous voulez ajouter un nouvel article, il vous faut donc

  • ajouter un bouton
  • assigner ce bouton à un script
  • copier une fonction existante en remplaçant ces valeurs

Recherche article et prix

La recherche du produit se fait grâce à la function « product ».
Cette fonction est l’une des pièces maîtresses de la caisse enregistreuse.

function product(lv_name){
  var range = 'A1:D44';
  var sheetname = 'Source';
  var searchRange = 'A1:A44';
  var row = findCell(lv_name, sheetname, searchRange);
  var price = getPrice(row, range, sheetname);
  var lv_case = getCase(row, range, sheetname);
  //Browser.msgBox(price)
  var TotalRange = 'K3:N25';
  var SearchTotalRange = 'K3:K25';
  var rowInTotal = findCell(lv_name, 'main', SearchTotalRange);
  //Browser.msgBox(rowInTotal)
  if (rowInTotal == ""){
  // insert a new row
    var lv_start_col = 'K'
    var lv_start_line = 3
    var lv_end_col = 'N'
    var TotalEmptyCell = getFirstEmptyCell(SearchTotalRange, lv_start_col, lv_end_col, lv_start_line)
    //Browser.msgBox(TotalEmptyCell)
    insertCell(TotalEmptyCell, lv_name, price, lv_case) 
  } else {
  // update the quantity
    //Browser.msgBox(rowInTotal)
    updateCell(TotalRange, rowInTotal, lv_case) 
  }
}
  • Le range ‘A1:D44’ représente les cellules dans lesquelles j’ai introduit mes différents produits et leur prix, si on ajoute/supprime des produits, il faut ajuster ce range.
  • Le SearchRange ‘A1:D44’ représente la première colonne, celui-ci est utilisé pour retrouver les produits par leur nom, même remarque que pour le range, il doit être ajusté si l’on ajoute/supprime des articles.
  • SheetName correspond au nom de votre sheet google
Recherche articles et prix dans google sheet

Identifier la ligne

La fonction FindCell bien aidée par le range, le nom de la sheet et le nom du produit permet de retrouver sur quelle ligne se trouve l’article

var row = findCell(lv_name, sheetname, searchRange);
function findCell(containingValue, sheetname, range) {
  var lv_cell
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName(sheetname);
  var r     = sheet.getRange(range);
  //var dataRange = sheet.getDataRange();
  var values = r.getValues();
  for (var i = 0; i < values.length; i++) {
    var row = ""; 
      if (values[i][0] == containingValue) {
        row = values[i][0];
        //Browser.msgBox(i)
        break
      }   
  }
  if (row != "") {
    lv_cell = i+1
  } else {
    lv_cell = ""
  }
  return lv_cell
}

Identifier le prix

Une fois que l’on connait la ligne, on peut retrouver le prix grâce à la function getPrice

var price = getPrice(row, range, sheetname);
function getPrice(pos, range, sheetname){
  var ss = SpreadsheetApp.openById("<identifiant de votre sheet>");
  var sheet = ss.getSheetByName(sheetname);
  var range = sheet.getRange(range);  
  var cell  = range.getCell(pos,3);
  var data = cell.getValue();
  return data
}

Comme on connait la ligne et la colonne (3 dans mon scenario), on peut extraire la valeur de la cellule.
A noter que dans la fonction SpreadsheetApp.openById(« id »), il faut placer l’identifiant de la sheet google que vous trouvez dans l’url

identifiant google sheet

Identifier le nombre de cases

Comme dans mon scénario, on fonctionne également avec un nombre de cases, similaire à la fonction getPrice, on a une fonction getCase.

function getCase(pos, range, sheetname){
  var ss = SpreadsheetApp.openById("<identifiant de votre sheet>");
  var sheet = ss.getSheetByName(sheetname);
  var range = sheet.getRange(range);  
  var cell  = range.getCell(pos,2);
  var data = cell.getValue();
  return data
}

La différence entre les deux fonctions est juste la colonne, le prix se trouve dans la colonne 3 et le nombre de cases dans la colonne 2.

Bon de commande

Une fois que l’on a retrouvé le prix et le nombre de cases, il reste à mettre à jour le bon de commande (la partie de droite sur la page principale de la sheet).

  var TotalRange = 'K3:N25';
  var SearchTotalRange = 'K3:K25';
  var rowInTotal = findCell(lv_name, 'main', SearchTotalRange);
  //Browser.msgBox(rowInTotal)
  if (rowInTotal == ""){
  // insert a new row
    var lv_start_col = 'K'
    var lv_start_line = 3
    var lv_end_col = 'N'
    var TotalEmptyCell = getFirstEmptyCell(SearchTotalRange, lv_start_col, lv_end_col, lv_start_line)
    //Browser.msgBox(TotalEmptyCell)
    insertCell(TotalEmptyCell, lv_name, price, lv_case) 
  } else {
  // update the quantity
    //Browser.msgBox(rowInTotal)
    updateCell(TotalRange, rowInTotal, lv_case) 

Le bon de commande est limité à 22 articles différents (‘K3:K25’) au besoin le range peut être étendu, 22 couvrait largement ma situation et me permettait de bien présenter sur mon écran. (pas besoin de scroller)

Bon de commande

Similairement à la recherche de produit dans la première sheet, ici on recherche dans la range ‘K3:K25’ si l’article est déjà sur le bon de commande avec la function findCell.
On se retrouve avec deux scénarios possibles:

l’article est déjà dans le bon de commande

Dans ce cas de figure, on va identifier sur quelle ligne l’article est présent et incrémenter la quantité

// update the quantity
     //Browser.msgBox(rowInTotal)
     updateCell(TotalRange, rowInTotal, lv_case)
function updateCell(range, row, lv_case) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var r     = sheet.getRange(range)
  var CellQuantity = Number(r.getCell(row,2).getValue());
  CellQuantity = CellQuantity + 1
  //Browser.msgBox(CellQuantity)
  r.getCell(row,2).setValue(CellQuantity);
  //var CellCase = r.getCell(row,5).getValue();
  //CellCase = CellCase 
  //r.getCell(row,5).setValue(CellCase);
}

Le prix unitaire et le nombre de cases étant déjà présent, le calcul des totaux de cette ligne se fait grâce à la formule assignée à la cellule.

  Caisse électronique avec GoogleSheet  - Total article
Caisse électronique avec GoogleSheet – Total article
L’article n’est pas présent sur le bon de commande:

Dans cette situation, on va identifier la première ligne vide et venir y insérer l’article, on doit donc insérer

  • le nom de l’article
  • la quantité = 1
  • le prix unitaire
  • le nombre de cases pour cet article
// insert a new row
    var lv_start_col = 'K'
    var lv_start_line = 3
    var lv_end_col = 'N'
    var TotalEmptyCell = getFirstEmptyCell(SearchTotalRange, lv_start_col, lv_end_col, lv_start_line)
    //Browser.msgBox(TotalEmptyCell)
    insertCell(TotalEmptyCell, lv_name, price, lv_case) 
function insertCell(cells, product, price, lv_case) {
  var sheet          = SpreadsheetApp.getActiveSheet();
  //var r            = sheet.getRange(range)
  var cell           = sheet.getRange(cells)
  var CellProduct    = cell.setValue(product);
  var CellQuantity   = cell.getCell(1,2).setValue(1);
  var CellPrice      = cell.getCell(1,3).setValue(price);
  var CellTotalPrice = 1 * price
  //Browser.msgBox(CellTotalPrice)
  //cell.getCell(1,4).setValue(CellTotalPrice);
  var CellCases      = Number(cell.getCell(1,4).setValue(lv_case));
  //Browser.msgBox(CellCases)
}

Supprimer un article de la commande

Pour ajouter un article sur le bon de commande, il suffit de cliquer sur la cellule de cet article, mais comment supprimer un article.
il y a deux solutions:

  • mise à jour manuelle de la quantité (tant que possible autant éviter)
  • mise à jour de la quantité via le bouton

Pour la mise à jour manuelle, il suffit de se rendre dans la colonne et mettre à jour la quantité

Mise à jour via le bouton

Sur chaque ligne du bon de commande, on retrouve le bouton , ce bouton est assigné à un script.
La différence entre les différents scripts est la ligne sur laquelle la quantité va être décrémentée, on retrouve donc la fonction « less_x » pour chaque ligne (22 fois, less_1 –> less_22).

function less_1(){
  less(MainSheet, QuantityRange, 1)
}

function less_2(){
  less(MainSheet, QuantityRange, 2)
}

function less_3(){
  less(MainSheet, QuantityRange, 3)
}
...
function less(sheetname,rangequantity, row){
  var lv_ss    = SpreadsheetApp.getActive();
  var lv_sheet = lv_ss.getSheetByName(sheetname)
  var lv_range = lv_sheet.getRange(rangequantity) 
  var lv_cell  = lv_range.getCell(row,1)
  var lv_value = lv_cell.getValues()
  //Browser.msgBox(lv_value)
  var new_value = lv_value - 1
  if ( new_value > 0){
    lv_cell.setValue(new_value) 
  } else {
    new_value = 0
    lv_cell.setValue(new_value)
  }
}

Il y a juste une vérification afin d’éviter les valeurs négatives.

Validation de commande

Après paiement de la commande, vous pouvez valider la commande afin de mettre à jour votre inventaire des ventes.

 Caisse électronique avec GoogleSheet  - Validation de la commande
Caisse électronique avec GoogleSheet – Validation de la commande

Cette fonction va identifier la ligne sur laquelle se trouve le produit dans la sheet inventaire et mettre à jour les colonnes (5 = Available, 6= Sell).
La colonne 5, pour autant qu’il y ait une valeur ( > 0) va être décrémentée de la quantité pour cet article sur le bon de commande.
Tandis que la colonne 6 sera incrémentée de cette même quantité.

function valider(){
  var totalrange = 'K3:L25'
  var totalsheet = 'main'
  var sourcerange = 'A2:F44'
  var sourcesheet = 'Source'
 
  valid(totalsheet, totalrange, sourcesheet, sourcerange)
  reinitialiser()
}

function valid(tsheet, trange, ssheet, srange){
  var ss     = SpreadsheetApp.getActive();
  var ts     = ss.getSheetByName(tsheet);
  var tr     = ts.getRange(trange);
 
  var ssh = ss.getSheetByName(ssheet);
  var sr  = ssh.getRange(srange);
  
  var tvalues = tr.getValues();
  for (var trow=0; trow<tvalues.length; trow++) {
      if (tvalues[trow][0] == "") {
        break
      } else {
        tproduct  = tvalues[trow][0]
        tquantity = tvalues[trow][1]
        //Browser.msgBox('produit=' + tproduct + ' quantite=' + tquantity)
        var srow = findCell(tproduct, ssheet, srange);
        //Browser.msgBox('Row in sourcetab=' + srow)
        updateSourceCell(ssheet, srange, srow, 5, tquantity)
        updateSourceCell(ssheet, srange, srow, 6, tquantity)
      }
  }  

function updateSourceCell(sheet, range, row, col, val) {
  var ss     = SpreadsheetApp.getActive();
  var ts     = ss.getSheetByName(sheet);
  var r      = ts.getRange(range)
  var CellQuantity = r.getCell(row,col).getValue();
  if (col == 5){
    if (CellQuantity > 0){
      r.getCell(row,col).setValue(CellQuantity-val);
    }
  }
  
  if (col == 6){
      r.getCell(row,col).setValue(CellQuantity+val);
  }  
}

Le total est lui réalisé automatiquement par la formule utilisée dans la cellule

Caisse électronique avec GoogleSheet – Inventaire & calcul du total

Le grand total afin de connaître les recettes de la journée est également calculé sur cette sheet.
Une fois l’inventaire mis à jour, le bon de commande est réinitialisé par la fonction « reinitialiser« 

Réinitialisation

Cette fonction fait « place propre » pour le client suivant

function reinitialiser(){
  var sourceRange = 'V3:Y24'
  var targetrange = 'K3:N24'
  var sheet       = 'main'
  reinit(sheet, sourceRange, targetrange)
}

function reinit(sheetname, sourcerange, targetrange ){
  var ss    = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName(sheetname);
  var r     = sheet.getRange(targetrange);  
  
  var sourceRange = sheet.getRange(sourcerange);
  
  if(r.isBlank()){
 	// the range is already initialize	
  } else {
    sourceRange.copyValuesToRange(sheet, 11, 14, 3, 24);
  }
  
  var Cellrecu     = sheet.getRange('D23:D23');
  Cellrecu.getCell(1,1).setValue(0);
  
}

Cette fonction va copier le range de cellules vide (‘V32:Y24’) sur le range utilisé pour notre bon de commande (‘K3:N24’) et va également s’assurer que la cellule qui contient le montant reçu (D23) est réinitialisée à 0

Caisse électronique avec GoogleSheet - réinitialisation
Caisse électronique avec GoogleSheet – réinitialisation

Tout le code

Voici le code complet de mon exemple, j’ai retiré l’id de ma googleSheet, vous devez mettre à jour la variable « MySheetID » avec l’id de votre sheet Google. L’ID se trouve dans l’url.

var QuantityRange = 'L3:L24'
var MainSheet     = 'main'
// You can find the sheet ID in the url
var MySheetID     = "please update wityh your sheet ID"

function less(sheetname,rangequantity, row){
  var lv_ss    = SpreadsheetApp.getActive();
  var lv_sheet = lv_ss.getSheetByName(sheetname)
  var lv_range = lv_sheet.getRange(rangequantity) 
  var lv_cell  = lv_range.getCell(row,1)
  var lv_value = lv_cell.getValues()
  //Browser.msgBox(lv_value)
  var new_value = lv_value - 1
  if ( new_value > 0){
    lv_cell.setValue(new_value) 
  } else {
    new_value = 0
    lv_cell.setValue(new_value)
  }
}

function less_1(){
  less(MainSheet, QuantityRange, 1)
}

function less_2(){
  less(MainSheet, QuantityRange, 2)
}

function less_3(){
  less(MainSheet, QuantityRange, 3)
}

function less_4(){
  less(MainSheet, QuantityRange, 4)
}

function less_5(){
  less(MainSheet, QuantityRange, 5)
}

function less_6(){
  less(MainSheet, QuantityRange, 6)
}

function less_7(){
  less(MainSheet, QuantityRange, 7)
}

function less_8(){
  less(MainSheet, QuantityRange, 8)
}

function less_9(){
  less(MainSheet, QuantityRange, 9)
}

function less_10(){
  less(MainSheet, QuantityRange, 10)
}

function less_11(){
  less(MainSheet, QuantityRange, 11)
}

function less_12(){
  less(MainSheet, QuantityRange, 12)
}

function less_13(){
  less(MainSheet, QuantityRange, 13)
}

function less_14(){
  less(MainSheet, QuantityRange, 14)
}

function less_15(){
  less(MainSheet, QuantityRange, 15)
}

function less_16(){
  less(MainSheet, QuantityRange, 16)
}

function less_17(){
  less(MainSheet, QuantityRange, 17)
}

function less_18(){
  less(MainSheet, QuantityRange, 18)
}

function less_19(){
  less(MainSheet, QuantityRange, 19)
}

function less_20(){
  less(MainSheet, QuantityRange, 20)
}

function less_21(){
  less(MainSheet, QuantityRange, 21)
}

function less_22(){
  less(MainSheet, QuantityRange, 22)
}

function valider(){
  var totalrange = 'K3:L25'
  var totalsheet = 'main'
  var sourcerange = 'A2:F44'
  var sourcesheet = 'Source'
 
  valid(totalsheet, totalrange, sourcesheet, sourcerange)
  reinitialiser()
}

function valid(tsheet, trange, ssheet, srange){
  var ss     = SpreadsheetApp.getActive();
  var ts     = ss.getSheetByName(tsheet);
  var tr     = ts.getRange(trange);
 
  var ssh = ss.getSheetByName(ssheet);
  var sr  = ssh.getRange(srange);
  
  var tvalues = tr.getValues();
  for (var trow=0; trow<tvalues.length; trow++) {
      if (tvalues[trow][0] == "") {
        break
      } else {
        tproduct  = tvalues[trow][0]
        tquantity = tvalues[trow][1]
        //Browser.msgBox('produit=' + tproduct + ' quantite=' + tquantity)
        var srow = findCell(tproduct, ssheet, srange);
        //Browser.msgBox('Row in sourcetab=' + srow)
        updateSourceCell(ssheet, srange, srow, 5, tquantity)
        updateSourceCell(ssheet, srange, srow, 6, tquantity)
      }
  }  
  
}

function reinitialiser(){
  var sourceRange = 'V3:Y24'
  var targetrange = 'K3:N24'
  var sheet       = 'main'
  reinit(sheet, sourceRange, targetrange)
}

function reinit(sheetname, sourcerange, targetrange ){
  var ss    = SpreadsheetApp.getActive();
  var sheet = ss.getSheetByName(sheetname);
  var r     = sheet.getRange(targetrange);  
  
  var sourceRange = sheet.getRange(sourcerange);
  
  if(r.isBlank()){
 	// the range is already initialize	
  } else {
    sourceRange.copyValuesToRange(sheet, 11, 14, 3, 24);
  }
  
  var Cellrecu     = sheet.getRange('D23:D23');
  Cellrecu.getCell(1,1).setValue(0);
  
}

function product(lv_name){
  var range = 'A1:D44';
  var sheetname = 'Source';
  var searchRange = 'A1:A44';
  var row = findCell(lv_name, sheetname, searchRange);
  var price = getPrice(row, range, sheetname);
  var lv_case = getCase(row, range, sheetname);
  //Browser.msgBox(price)
  var TotalRange = 'K3:N25';
  var SearchTotalRange = 'K3:K25';
  var rowInTotal = findCell(lv_name, 'main', SearchTotalRange);
  //Browser.msgBox(rowInTotal)
  if (rowInTotal == ""){
  // insert a new row
    var lv_start_col = 'K'
    var lv_start_line = 3
    var lv_end_col = 'N'
    var TotalEmptyCell = getFirstEmptyCell(SearchTotalRange, lv_start_col, lv_end_col, lv_start_line)
    //Browser.msgBox(TotalEmptyCell)
    insertCell(TotalEmptyCell, lv_name, price, lv_case) 
  } else {
  // update the quantity
    //Browser.msgBox(rowInTotal)
    updateCell(TotalRange, rowInTotal, lv_case) 
  }
}

function tombola_2() {
  var lv_product = 'Tombola 2 tickets'
  product(lv_product)
}

function tombola_4() {
  var lv_product = 'Tombola 4 tickets'
  product(lv_product)
}

function tombola_10() {
  var lv_product = 'Tombola 10 tickets'
  product(lv_product)
}

function sauce() {
  var lv_product = 'Sauce'
  product(lv_product)
}

function pays_noir() {
  var lv_product = 'Pays Noir'
  product(lv_product)
}

function carte_complete() {
  var lv_product = 'Carte Complète'
  product(lv_product)
}

function bout_vin() {
  var lv_product = 'Bouteille de vin'
  product(lv_product)
}

function blanche() {
  var lv_product = 'Blanche'
  product(lv_product)
}

function apero() {
  var lv_product = 'Apero'
  product(lv_product)
}

function tombola() {
  var lv_product = 'Tombola'
  product(lv_product)
}

function canard5() {
  var lv_product = 'Peche aux canards_5'
  product(lv_product)
}

function canard12() {
  var lv_product = 'Peche aux canards_12'
  product(lv_product)
}

function canard18() {
  var lv_product = 'Peche aux canards_18'
  product(lv_product)
}

function canard25() {
  var lv_product = 'Peche aux canards_25'
  product(lv_product)
}

function canard20() {
  var lv_product = 'Peche aux canards_24'
  product(lv_product)
}

function pain_sauc_broch_merg() {
  var lv_product = 'Pain saucisse/brochette/merguez'
  product(lv_product)
}

function pizza() {
  var lv_product = 'Pizza'
  product(lv_product)
}

function petite_frite() {
  var lv_product = 'Petite frite'
  product(lv_product)
}

function chips() {
  var lv_product = 'Chips'
  product(lv_product)
}

function glace_2boules() {
  var lv_product = 'Glace'
  product(lv_product)
}

function brochette_bonbons() {
  var lv_product = 'Brochette bonbons'
  product(lv_product)
}

function grande_frite() {
  var lv_product = 'Grande frite'
  product(lv_product)
}

function pain_brochette() {
  var lv_product = 'Pain brochette'
  product(lv_product)
}

function pain_saucisse() {
  var lv_product = 'Pain saucisse'
  product(lv_product)
}

function leffe() {
  var lv_product = 'Leffe'
  product(lv_product)
}

function verre_de_vin() {
  var lv_product = 'Verre de vin'
  product(lv_product)
}

function marron() {
  var lv_product = 'Marrons chauds'
  product(lv_product)
}

function cougnou() {
  var lv_product = 'Cougnou'
  product(lv_product)
}

function hot_dog() {
  var lv_product = 'Hot-Dog'
  product(lv_product)
}

function pain_boudin() {
  var lv_product = 'Pain boudin'
  product(lv_product)
}

function tartiflette() {
  var lv_product = 'Tartiflette'
  product(lv_product)
}

function jupiler() {
  var lv_product = 'Jupiler'
  product(lv_product)
}

function xmas() {
  var lv_product = 'XMas'
  product(lv_product)
}


function kriek() {
  var lv_product = 'Kriek'
  product(lv_product)
}

function cafe() {
  var lv_product = 'Café'
  product(lv_product)
}

function cacao() {
  var lv_product = 'Cacao'
  product(lv_product)
}

function peket() {
  var lv_product = 'Peket'
  product(lv_product)
}

function vin_chaud() {
  var lv_product = 'Vin chaud'
  product(lv_product)
}

function eau_petillante() {
  var lv_product = 'Eau pétillante'
  product(lv_product)
}

function fanta() {
  var lv_product = 'Fanta'
  product(lv_product)
}

function limonade() {
  var lv_product = 'Limonade'
  product(lv_product)
}


function coca() {
  var lv_product = 'Coca'
  product(lv_product)
}

function coca_zero() {
  var lv_product = 'Coca Zero'
  product(lv_product)
}

function eau() {
  var lv_product = 'Eau'
  product(lv_product)
}

function getPrice(pos, range, sheetname){
  var ss = SpreadsheetApp.openById(MySheetID);
  var sheet = ss.getSheetByName(sheetname);
  var range = sheet.getRange(range);  
  var cell  = range.getCell(pos,3);
  var data = cell.getValue();
  return data
}

function getCase(pos, range, sheetname){
  var ss = SpreadsheetApp.openById(MySheetID);
  var sheet = ss.getSheetByName(sheetname);
  var range = sheet.getRange(range);  
  var cell  = range.getCell(pos,2);
  var data = cell.getValue();
  return data
}

function findCell(containingValue, sheetname, range) {
  var lv_cell
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName(sheetname);
  var r     = sheet.getRange(range);
  //var dataRange = sheet.getDataRange();
  var values = r.getValues();
  for (var i = 0; i < values.length; i++) {
    var row = ""; 
      if (values[i][0] == containingValue) {
        row = values[i][0];
        //Browser.msgBox(i)
        break
      }   
  }
  if (row != "") {
    lv_cell = i+1
  } else {
    lv_cell = ""
  }
  return lv_cell
}

function getFirstEmptyCell(range, Startcol, EndCold, Startline) {
  var lv_value
  var sheet  = SpreadsheetApp.getActiveSheet();
  var r      = sheet.getRange(range); 
  var values = r.getValues();
  for (var row=0; row<values.length; row++) {
    //Browser.msgBox(values[row][0])
      if (values[row][0] == "") {
        break
      }       
  }
  lv_row = Startline + row
  lv_value = Startcol + lv_row.toString() + ':' + EndCold + lv_row.toString()
  //Browser.msgBox(lv_value)
  return (lv_value);
}

function insertCell(cells, product, price, lv_case) {
  var sheet          = SpreadsheetApp.getActiveSheet();
  //var r            = sheet.getRange(range)
  var cell           = sheet.getRange(cells)
  var CellProduct    = cell.setValue(product);
  var CellQuantity   = cell.getCell(1,2).setValue(1);
  var CellPrice      = cell.getCell(1,3).setValue(price);
  var CellTotalPrice = 1 * price
  //Browser.msgBox(CellTotalPrice)
  //cell.getCell(1,4).setValue(CellTotalPrice);
  var CellCases      = Number(cell.getCell(1,4).setValue(lv_case));
  //Browser.msgBox(CellCases)
}

function updateCell(range, row, lv_case) {
  var sheet = SpreadsheetApp.getActiveSheet();
  var r     = sheet.getRange(range)
  var CellQuantity = Number(r.getCell(row,2).getValue());
  CellQuantity = CellQuantity + 1
  //Browser.msgBox(CellQuantity)
  r.getCell(row,2).setValue(CellQuantity);
  //var CellCase = r.getCell(row,5).getValue();
  //CellCase = CellCase 
  //r.getCell(row,5).setValue(CellCase);
}

function updateSourceCell(sheet, range, row, col, val) {
  var ss     = SpreadsheetApp.getActive();
  var ts     = ss.getSheetByName(sheet);
  var r      = ts.getRange(range)
  var CellQuantity = r.getCell(row,col).getValue();
  if (col == 5){
    if (CellQuantity > 0){
      r.getCell(row,col).setValue(CellQuantity-val);
    }
  }
  
  if (col == 6){
      r.getCell(row,col).setValue(CellQuantity+val);
  }  
  
}

Conclusions

Après une première expérience, je ne suis pas trop mécontent du résulat, pour les commandes simples c’est un peu lent mais d’un autre côté on a un historique des ventes.
Dommage que ça ne fonctionne pas sur tablette et qu’il faut être online.
Pour le reste je pense que ça couvre assez bien les besoins, c’est gratuit et assez simple à mettre à jour.
Si vous avez des suggestions ou questions, n’hésitez pas à commenter

3 thoughts on “Caisse électronique avec GoogleSheet

  1. Fury

    Salut,

    Cela fonctionne pour moi Merci 🙂

    j’aimerais avoir de l’aide pour ca :
    J’ai des articles non soldé et les même articles soldé
    Comment puis faire pour utilisé les même quantité en stock afin que cela décrément exemple :

    Article Prix Stock
    Jus de pomme $35,00> 67
    Jus de pomme -10% $31,50>

    Sur le jus de pomme normal cela fonction mais j’aimerais lorsque que je valide une commande avec le jus de pomme à -10% que cela enlève la quantité de jus de pomme normal car ce sont les deux même produits. Merci par avance

    Reply
  2. Capucine

    Bonjour,
    Lorsque je reproduis exactement votre tableau et votre code et que j’appuie sur un « produit » pour essayer, google sheet m’indique : Exception : Valeur incorrecte
    Que dois je faire ?

    Reply
    1. SebastienMa Post author

      Bonjour, je vous avoue que ce n’est pas évident de répondre avec si peu d’information, ce que je peux vous conseiller c’est d’ajouter quelques « Browser.msgBox() » à différents endroits dans le code pour vous aider à identifier quelle partie du code pose problème.

      A première vue votre erreur me fait penser que vous n’avez pas changé l’ID par celui de votre sheet google.

      Dans les fonctions getCase() et getPrice(), il est nécessaire de remplacer ‘id‘ par l’identifiant de votre sheet google:

      function getCase(pos, range, sheetname){
      var ss = SpreadsheetApp.openById(« id« );

      function getPrice(pos, range, sheetname){
      var ss = SpreadsheetApp.openById(« id« );

      l’identifiant est la partie que vous retrouvez dans l’url entre le /d/ et le /edit..:https://docs.google.com/spreadsheets/d/id/edit...

      Dans la dernière version, j’ai créé une variable au tout début du script
      MySheetID = ‘id‘ et j’utilise cette variable dans les functions

      function getCase(pos, range, sheetname){
      var ss = SpreadsheetApp.openById(MySheetID);

      function getPrice(pos, range, sheetname){
      var ss = SpreadsheetApp.openById(MySheetID);

      voilà j’espère que ça vous débloquera.

      Reply

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.