Commit 32241a99 by Damien Moulard

merge conflict

parents a15908ef 71fcc738
dev_cooperatic #5673_bug_calendrier_echange_service 3832-makeups-and-member-status-update 4081 4444_improve_presence_recording 4709 4778-reception-dont-get-finished-orders 4809-remove-shelf-value-col-to-reduce-server-load 4880-rapports-reception-faux 4950-douchage-appli-reception 5474-et-5462-Voir-les-rattrapages-choisis-dans-admin-bdm-et-corrige-lenteur-affichage-admin-rattrapages 5641-reception-trier-a-la-maj-prix-dans-ordre-de-pointage-quantites 6286_bug_encaissement_souscription_cheque_espece 6813-marking-parent-gone-when-unpairing-binom-does-not-unsuscribe-parent-from-shift-template 6832--certaines-absences-engendrent-une-erreur 7723-7559-change-purchase-order-workflow-django-side 7731-third-party-side-brinks-pos-export-not-working 7747-inventaire-par-article 7800-make-test-solution-work 7848-cannot-validate-qty-with-decimal-on-kg-product 7918_bug_quantites_stade_demande_prix adaptation_supercafoutch adaptation_supercoop adaptation_supercoop_supercafoutch adpatation_chouette assistance_import_article coop_dev_necessitant_modules_bdm_odoo_modifies correctif_nb_rattrapages_creation_binome_avec_ajout_automatique_au_point_negatif dev_lgds dev_principale dev_principale_clean docker export_capital_detenu fix_bug_process_picking fusion_custom_graoucoop graoucoop_backup graoucoop_prod graoucoop_tmp hot_fix_shelf_labels_auto_print howto impression_etiquettes_rayons integration_lien_precommandes_dans_espace_membre lacagette_prod local_branch master meal-voucher-and-label-printer-software-bug migration-v12 pour_graoucoop_prod pour_version_prod_cagette refonte_espace_membre_sc retouches_tickets_supercoop sc-setup-stock-app supercafoutch-preprod supercafoutch-prod-20221003 supercafoutch_prod ticket_4146 20210701 supercafoutch_20250120_151258 supercafoutch_20250120_150340 supercafoutch_20240909_080630 supercafoutch_20240609_115709 supercafoutch_20240212_082431 supercafoutch_20240107_181851 supercafoutch_prod_until_240107 supercafoutch-prod-20221003 supercafoutch-230911 supercafoutch-230824 supercafoutch-230823 supercafoutch-230823-the-true-one migration-v12-tag lacagette_20240310_074751 lacagette_20240107_122554 lacagette_20240107_120916 graoucoop_20240609_122614 cagette_testtag cagette-230814 cagette-230630
3 merge requests!40Add Howto page (to explain how to use 'Odoo user connect' feature),!106Dev principale,!45Intégration des Dev cooperatic (Aide à la commande, Réception avec cache couchDB, possibilité de valider une présence Comité)
Pipeline #1109 failed with stage
in 1 minute 19 seconds
var suppliers_list = [],
products_list = [],
products_table = null,
products = [],
selected_suppliers = [],
......@@ -67,6 +68,67 @@ function dates_diff(date1, date2) {
return diff;
}
/* - PRODUCTS */
/**
* Add a product.
*
* @returns -1 if validation failed, 0 otherwise
*/
function add_product() {
const user_input = $("#product_input").val();
// Check if user input is a valid article
const product = products_list.find(s => s.display_name === user_input);
if (product === undefined) {
alert("L'article renseigné n'est pas valide.\n"
+ "Veuillez sélectionner un article dans la liste déroulante.");
return -1;
}
const product_exists = products.findIndex(p => p.name === user_input);
if (product_exists !== -1) {
alert("Cet article est déjà dans le tableau.");
$("#product_input").val('');
return -1;
}
$.ajax({
type: 'GET',
url: '/products/get_product_for_help_order_line/' + product.tpl_id,
dataType:"json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function(data) {
if (typeof data.id != "undefined") {
data.suppliersinfo = [];
data.default_code = ' ';
products.unshift(data);
update_main_screen({'sort_order_dir':'desc'});
update_cdb_order();
} else {
alert("L'article n'a pas toutes les caractéristiques pour être ajouté.")
}
$("#product_input").val('');
},
error: function(data) {
err = {msg: "erreur serveur lors de la récupération des données liées à l'article", ctx: 'get_product_for_help_order_line'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
alert('Erreur lors de la récupération des informations, réessayer plus tard.');
}
});
return 0;
}
/* - SUPPLIERS */
/**
......@@ -842,7 +904,7 @@ function prepare_datatable_columns() {
/**
* Display the Datatable containing the products
*/
function display_products() {
function display_products(params) {
if (products.length == 0) {
$('.main').hide();
$('#create_orders').hide();
......@@ -859,14 +921,17 @@ function display_products() {
const data = prepare_datatable_data();
const columns = prepare_datatable_columns();
let sort_order_dir = "asc";
if (params != undefined && typeof params.sort_order_dir != "undefined") {
sort_order_dir = params.sort_order_dir;
}
products_table = $('#products_table').DataTable({
data: data,
columns: columns,
order: [
[
5, // Order by default by first supplier
"asc"
6, // Order by default by first supplier
sort_order_dir
]
],
stripeClasses: [], // Remove datatable cells coloring
......@@ -1027,7 +1092,7 @@ function unselect_all_rows() {
/**
* Update DOM display on main screen
*/
function update_main_screen() {
function update_main_screen(params) {
// Remove listener before recreating them
$('#products_table').off('input', 'tbody td .product_qty_input');
$('#products_table').off('click', 'tbody .product_not_from_supplier');
......@@ -1037,7 +1102,7 @@ function update_main_screen() {
$(".order_name_container").text(order_doc._id);
display_suppliers();
display_products();
display_products(params);
// Re-select previously selected rows
if (selected_rows.length > 0) {
......@@ -1192,6 +1257,11 @@ $(document).ready(function() {
add_supplier();
});
$("#product_form").on("submit", function(e) {
e.preventDefault();
add_product();
});
$("#do_inventory").on("click", function() {
generate_inventory();
});
......@@ -1304,7 +1374,7 @@ $(document).ready(function() {
source: suppliers_list.map(a => a.display_name)
});
closeModal();
},
error: function(data) {
err = {msg: "erreur serveur lors de la récupération des fournisseurs", ctx: 'get_suppliers'};
......@@ -1317,4 +1387,62 @@ $(document).ready(function() {
alert('Erreur lors de la récupération des fournisseurs, rechargez la page plus tard');
}
});
//Get products
var accentMap = {
"á": "a",
"à": "a",
"â": "a",
"é": "e",
"è": "e",
"ê": "e",
"ë": "e",
"ç": "c",
"ù": "u",
"ü": "u",
"ö": "o"
};
var normalize = function( term ) {
var ret = "";
for ( var i = 0; i < term.length; i++ ) {
ret += accentMap[ term.charAt(i) ] || term.charAt(i);
}
return ret;
};
$.ajax({
type: 'GET',
url: "/products/simple_list",
dataType:"json",
traditional: true,
contentType: "application/json; charset=utf-8",
success: function(data) {
products_list = data.list;
// Set up autocomplete on product input
$("#product_input").autocomplete({
source: function( request, response ) {
var matcher = new RegExp( $.ui.autocomplete.escapeRegex( request.term ), "i" );
response( $.grep( products_list.map(a => a.display_name), function( value ) {
value = value.label || value.value || value;
return matcher.test( value ) || matcher.test( normalize( value ) );
}) );
},
position: {collision: "flip" }
});
closeModal();
},
error: function(data) {
err = {msg: "erreur serveur lors de la récupération des articles", ctx: 'get_products'};
if (typeof data.responseJSON != 'undefined' && typeof data.responseJSON.error != 'undefined') {
err.msg += ' : ' + data.responseJSON.error;
}
report_JS_error(err, 'orders');
closeModal();
alert('Erreur lors de la récupération des articles, rechargez la page plus tard');
}
});
});
......@@ -165,10 +165,34 @@ class CagetteProduct(models.Model):
return res
@staticmethod
def get_product_for_help_order_line(product_tmpl_id):
api = OdooAPI()
res = []
try:
f = ["id", "state", "name", "default_code", "qty_available", "incoming_qty", "uom_id", "purchase_ok"]
# TODO fetch only 'purchase_ok' products ?
c = [['id', '=', product_tmpl_id], ['purchase_ok', '=', True]]
products_t = api.search_read('product.template', c, f)
res = [p for p in products_t if p["state"] != "end" and p["state"] != "obsolete"]
except Exception as e:
coop_logger.error("Odoo API get_product_for_help_order_line (tpl_id = %s) : %s", str(product_tmpl_id), str(e))
return res
class CagetteProducts(models.Model):
"""Initially used to make massive barcode update."""
@staticmethod
def get_simple_list():
res = []
api = OdooAPI()
try:
res = api.execute('lacagette.products', 'get_simple_list', {'only_purchase_ok': True})
except Exception as e:
coop_logger.error("Odoo api products simple list : %s", str(e))
return res
@staticmethod
def __unique_product_list(plist):
# 276
upl = {}
......
......@@ -4,6 +4,8 @@ from . import views
urlpatterns = [
url(r'^$', views.home),
url(r'^simple_list$', views.get_simple_list),
url(r'^get_product_for_help_order_line/([0-9]+)$', views.get_product_for_help_order_line),
url(r'^get_product_data$', views.get_product_data),
url(r'^get_products_stdprices$', views.get_products_stdprices),
url(r'^update_product_stock$', views.update_product_stock),
......
......@@ -26,6 +26,33 @@ def home(request):
return HttpResponse(template.render(context, request))
def get_simple_list(request):
res = {}
try:
res = CagetteProducts.get_simple_list()
except Exception as e:
coop_logger.error("Get products simple list : %s", str(e))
res['error'] = str(e)
if ('error' in res):
return JsonResponse(res, status=500)
else:
return JsonResponse(res, safe=False)
def get_product_for_help_order_line(request, tpl_id):
res = {}
try:
result = CagetteProduct.get_product_for_help_order_line(tpl_id)
if len(result) == 1:
res = result[0]
except Exception as e:
coop_logger.error("get_product_for_help_order_line : %s", str(e))
res['error'] = str(e)
if ('error' in res):
return JsonResponse(res, status=500)
else:
return JsonResponse(res, safe=False)
def get_product_data(request):
barcode = request.GET['barcode']
res = CagetteProduct.get_product_from_barcode(barcode)
......
......@@ -61,7 +61,14 @@
</div>
<div id="orders_creation_area">
<div class="add_product_container"></div>
<div class="add_product_container">
<div id="product_form_container">
<form action="javascript:;" id="product_form">
<input type="text" name="article" id="product_input" placeholder="Rechercher un article">
<button type="submit" class='btn--primary'>Ajouter l'article</button>
</form>
</div>
</div>
<button type="button" class='btn--primary' id="create_orders" style="display:none;">
Générer les commandes
</button>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment