use LWP::Authen::Digest;
use SL::DB::ShopOrder;
use SL::DB::ShopOrderItem;
+use SL::DB::PaymentTerm;
use SL::DB::History;
use SL::DB::File;
use Data::Dumper;
if($answer->{success}) {
my $shoporder = $answer->{data};
+ $main::lxdebug->dump(0, 'WH: ANSWER ', $answer);
$dbh->with_transaction( sub{
#update status on server
$shoporder->{status} = "processing";
- my $answer = $self->set_orderstatus($shoporder->{id}, "fetched");
+ my $answer = $self->set_orderstatus($shoporder->{id}, "completed");
unless($answer){
push @errors,($::locale->text('Saving failed. Error message from the server: #1', $answer->message));
return 0;
"orders",
undef,
"get",
- "&per_page=$otf&status=pending"
+ "&per_page=$otf&status=processing&after=2020-12-31T23:59:59&order=asc"
);
my %fetched_orders;
if($answer->{success}) {
my $orders = $answer->{data};
foreach my $shoporder(@{$orders}){
-
$dbh->with_transaction( sub{
#update status on server
- $shoporder->{status} = "processing";
- my $anser = $self->set_orderstatus($$shoporder->{id}, "fetched");
+ $shoporder->{status} = "completed";
+ my $anwser = $self->set_orderstatus($shoporder->{id}, "completed");
unless($answer){
push @errors,($::locale->text('Saving failed. Error message from the server: #1', $answer->message));
return 0;
my @positions = sort { Sort::Naturally::ncmp($a->{"sku"}, $b->{"sku"}) } @{ $import->{line_items} };
my $position = 1;
- my $answer= $self->send_request("taxes");
- unless ($answer->{success}){ return 0;}
- my %taxes = map { ($_->{id} => $_) } @{ $answer->{data} };
-
my $active_price_source = $self->config->price_source;
+ my $tax_included = $self->config->pricetype eq 'brutto' ? 1 : 0;
#Mapping Positions
foreach my $pos(@positions) {
- my $price = $::form->round_amount($pos->{total},2);
- my $tax_id = $pos->{taxes}[0]->{id};
- my $tax_rate = $taxes{ $tax_id }{rate};
+ my $tax_rate = $pos->{tax_class} eq "reduced-rate" ? 7 : 19;
+ my $tax_factor = $tax_rate/100+1;
+ my $price = $pos->{price};
+ if ( $tax_included ) {
+ $price = $price * $tax_factor;
+ $price = $::form->round_amount($price,2);
+ } else {
+ $price = $::form->round_amount($price,2);
+ }
my %pos_columns = ( description => $pos->{name},
partnumber => $pos->{sku}, # sku has to be a valid value in WooCommerce
price => $price,
shop_order_id => $id,
active_price_source => $active_price_source,
);
- #$main::lxdebug->dump(0, "TST: WooCommerce save pos", $pos);
- #$main::lxdebug->dump(0, "TST: WooCommerce save pos_columns", \%pos_columns);
my $pos_insert = SL::DB::ShopOrderItem->new(%pos_columns);
$pos_insert->save;
$position++;
}
$shop_order->positions($position-1);
+ if ( $self->config->shipping_costs_parts_id ) {
+ my $shipping_part = SL::DB::Manager::Part->find_by( id => $self->config->shipping_costs_parts_id);
+ my %shipping_pos = (
+ description => $import->{data}->{dispatch}->{name},
+ partnumber => $shipping_part->partnumber,
+ price => $import->{data}->{invoiceShipping},
+ quantity => 1,
+ position => $position,
+ shop_trans_id => 0,
+ shop_order_id => $id,
+ );
+ my $shipping_pos_insert = SL::DB::ShopOrderItem->new(%shipping_pos);
+ $shipping_pos_insert->save;
+ }
+
my $customer = $shop_order->get_customer;
if(ref($customer)){
);
my $shop_id = $self->config->id;
+ my $tax_included = $self->config->pricetype;
# Mapping to table shoporders. See https://woocommerce.github.io/woocommerce-rest-api-docs/?shell#order-properties
+ my $d_street;
+ if ( $import->{shipping}->{address_1} ne "" ) {
+ $d_street = $import->{shipping}->{address_1} . ($import->{shipping}->{address_2} ? " " . $import->{shipping}->{address_2} : "");
+ } else {
+ $d_street = $import->{billing}->{address_1} . ($import->{billing}->{address_2} ? " " . $import->{billing}->{address_2} : "");
+ }
+ # Mapping Zahlungsmethoden muss an Firmenkonfiguration angepasst werden
+ my %payment_ids_methods = (
+ # woocommerce_payment_method_title => kivitendo_payment_id
+ );
+ my $default_payment = SL::DB::Manager::PaymentTerm->get_first();
+ my $default_payment_id = $default_payment ? $default_payment->id : undef;
my %columns = (
-#billing
+#billing Shop can have different billing addresses, and may have 1 customer_address
billing_firstname => $import->{billing}->{first_name},
billing_lastname => $import->{billing}->{last_name},
#address_1 address_2
#billing_greeting => "",
#billing_fax => "",
#billing_vat => "",
- #billing_company => "",
+ billing_company => $import->{billing}->{company},
#billing_department => "",
#customer
#customer_vat => "",
#shipping
- delivery_firstname => $import->{shipping}->{first_name},
- delivery_lastname => $import->{shipping}->{last_name},
- delivery_company => $import->{shipping}->{company},
+ delivery_firstname => $import->{shipping}->{first_name} || $import->{billing}->{first_name},
+ delivery_lastname => $import->{shipping}->{last_name} || $import->{billing}->{last_name},
+ delivery_company => $import->{shipping}->{company} || $import->{billing}->{company},
#address_1 address_2
- delivery_street => $import->{shipping}->{address_1} . ($import->{shipping}->{address_2} ? " " . $import->{shipping}->{address_2} : ""),
- delivery_city => $import->{shipping}->{city},
+ delivery_street => $d_street,
+ delivery_city => $import->{shipping}->{city} || $import->{billing}->{city},
#state ???
- delivery_zipcode => $import->{shipping}->{postcode},
- delivery_country => $import->{shipping}->{country},
+ delivery_zipcode => $import->{shipping}->{postcode} || $import->{billing}->{postcode},
+ delivery_country => $import->{shipping}->{country} || $import->{billing}->{country},
#delivery_department => "",
#delivery_email => "",
#delivery_fax => "",
#discount_total
#discount_tax
#shipping_total
- shipping_costs => $import->{shipping_costs},
+ shipping_costs => $import->{shipping_total},
#shipping_tax
- shipping_costs_net => $import->{shipping_costs} - $import->{shipping_tax},
+ shipping_costs_net => $import->{shipping_total},
#cart_tax
#total
amount => $import->{total},
#total_tax
netamount => $import->{total} - $import->{total_tax},
#prices_include_tax
- tax_included => $import->{prices_include_tax} eq "true" ? 1 : 0,
+ tax_included => $tax_included,
#payment_method
- # ??? payment_id => $import->{payment_method},
+ payment_id => $payment_ids_methods{$import->{payment_method}} || $default_payment_id,
#payment_method_title
- payment_description => $import->{payment}->{payment_method_title},
+ payment_description => $import->{payment_method_title},
#transaction_id
shop_trans_id => $import->{id},
#date_paid
#};
my @categories = ();
- if ($shop_part->shop_category) {
- foreach my $row_cat ( @{ $shop_part->shop_category } ) {
- my $temp = { ( id => @{$row_cat}[0], ) };
- push ( @categories, $temp );
- }
+ foreach my $row_cat ( @{ $shop_part->shop_category } ) {
+ my $temp = { ( id => @{$row_cat}[0], ) };
+ push ( @categories, $temp );
}
#my @upload_img = $shop_part->get_images;
- my $partnumber = $::form->escape($part->partnumber);#don't accept / in partnumber
+ my $partnumber = $::form->escape($part->partnumber);#don't accept / in articlenumber
my $stock_status = ($part->onhand ? "instock" : "outofstock");
my $status = ($shop_part->active ? "publish" : "private");
my $tax_n_price = $shop_part->get_tax_and_price;
# don't know if this is needed
#if(@upload_img) {
- # my $partnumber = $::form->escape($part->partnumber);#shopware don't accept / in partnumber
- # my $imgup = $self->connector->put($url . "api/generatepartimages/$partnumber?useNumberAsId=true");
+ # my $partnumber = $::form->escape($part->partnumber);#shopware don't accept / in articlenumber
+ # my $imgup = $self->connector->put($url . "api/generatearticleimages/$partnumber?useNumberAsId=true");
#}
return $answer->{success};
}
-sub get_article_info {
+sub get_article {
my ($self) = @_;
my $partnumber = $_[1];
$partnumber = $::form->escape($partnumber);#don't accept / in partnumber
my $answer = $self->send_request("products/", undef , "get" , "&sku=$partnumber");
- $answer->{data} = $answer->{data}[0];
- #$main::lxdebug->dump(0, "TST: WooCommerce get_part_info ", $answer);
- return $answer;
-
if($answer->{success} && scalar @{$answer->{data}}){
- my $part = $self->map_data_to_part($answer->{data}[0]);
- #$main::lxdebug->dump(0, "TST: WooCommerce get_part_info part", $part);
- return $part;
+ my $article = $answer->{data}[0];
+ return $article;
} else {
#What shut be here?
return $answer
}
}
-sub map_data_to_part {
- my ($self, $part_data) = @_;
-
- my %map_part_data = (
- #id => $part_data->{},
- partnumber => $part_data->{sku},
- description => $part_data->{name},
- #listprice => $part_data->{},
- #sellprice => $part_data->{},
- #lastcost => $part_data->{},
- #priceupdate => $part_data->{},
- #weight => $part_data->{},
- notes => $part_data->{description},
- #makemodel => $part_data->{},
- #rop => $part_data->{},
- shop => 1,
- obsolete => 0,
- #bom => $part_data->{},
- #image => $part_data->{},
- #drawing => $part_data->{},
- #microfiche => $part_data->{},
- #partsgroup_id => $part_data->{},
- #ve => $part_data->{},
- #gv => $part_data->{},
- #itime => $part_data->{},
- #mtime => $part_data->{},
- #unit => $part_data->{},
- unit => 'Stck',
- #formel => $part_data->{},
- #not_discountable => $part_data->{},
- #buchungsgruppen_id => $part_data->{},
- #payment_id => $part_data->{},
- #ean => $part_data->{},
- #price_factor_id => $part_data->{},
- #onhand => $part_data->{},
- #stockable => $part_data->{},
- #has_sernumber => $part_data->{},
- #warehouse_id => $part_data->{},
- #bin_id => $part_data->{},
- #df_status_aktuell => $part_data->{},
- #df_status_verlauf => $part_data->{},
- #active => $part_data->{},
- #classification_id => $part_data->{},
- part_type => 'part',
- );
- return SL::DB::Part->new(%map_part_data);
-}
-
-sub map_data_to_shop_part {
- my ($self, $part_data, $part) = @_;
-
- my @categories = ();
- foreach my $row_cat ( @{ $part_data->{categories} } ) {
- my @tmp;
- push( @tmp,$row_cat->{id} );
- push( @tmp,$row_cat->{name} );
- push( @categories,\@tmp );
- }
- my %map_shop_part_data = (
- #id => ,
- shop_id => $self->config->id,
- part_id => $part->id,
- shop_description => $part_data->{description},
- #itime => ,
- #mtime => ,
- #last_update => ,
- #show_date => ,
- sortorder => $part_data->{menu_order},
- #front_page => ,
- active => 1,
- shop_category => \@categories,
- #active_price_source => ,
- #metatag_keywords => ,
- #metatag_description => ,
- #metatag_title => ,
- #shop_versandhinweis => ,
- );
- return SL::DB::ShopPart->new(%map_shop_part_data);
-}
-sub get_shop_parts {
- my ($self, $partnumber) = @_;
-
- my $dbh = SL::DB::client;
- my @errors;
- my $number_of_parts = 0;
- my %fetched_parts;
- my $answer;
-
- if ($partnumber) {
- $partnumber = $::form->escape($partnumber);#don't accept / in partnumber
- $answer = $self->send_request("products/", undef , "get" , "&sku=$partnumber");
- } else {
- #TODO
- $answer = $self->send_request("products/", undef , "get");
- if ($answer->{total_pages} > 1) {
- my $current_page = 2;
- while ($current_page <= $answer->{total_pages}) {
- my $tmp_answer = $self->send_request("products/", undef , "get", "&page=$current_page");
- foreach my $part (@{$tmp_answer->{data}}) {
- push @{$answer->{data}} , $part;
- }
- $current_page++;
- }
- }
- }
-
- if($answer->{success} && scalar @{$answer->{data}}){
- $dbh->with_transaction( sub{
- foreach my $part_data (@{$answer->{data}}) {
- unless (!$part_data->{sku} || SL::DB::Manager::Part->get_all_count( query => [ partnumber => $part_data->{sku} ] )) {
- my $part = $self->map_data_to_part($part_data);
- #$main::lxdebug->dump(0, "TST: WooCommerce get_shop_parts part ", $part);
- $part->save;
- my $shop_part = $self->map_data_to_shop_part($part_data, $part);
- #$main::lxdebug->dump(0, "TST: WooCommerce get_shop_parts shop_part ", $shop_part);
- $shop_part->save;
- $number_of_parts++;
- }
- }
- return 1;
- })or do {
- push @errors,($::locale->text('Saving failed. Error message from the database: #1', $dbh->error));
- };
-
- if(@errors){
- flash_later('error', $::locale->text('Errors: #1', @errors));
- }
- %fetched_parts = (
- shop_id => $self->config->id,
- shop_description => $self->config->description,
- number_of_parts => $number_of_parts,
- );
- } else {
- my %error_msg = (
- shop_id => $self->config->id,
- shop_description => $self->config->description,
- message => $answer->{message},
- error => 1,
- );
- %fetched_parts = %error_msg;
- }
- return \%fetched_parts;
-}
-
sub get_categories {
my ($self) = @_;
- my $answer = $self->send_request("products/categories");
+ my $answer = $self->send_request("products/categories",undef,"get","&per_page=100");
unless($answer->{success}) {
return $answer;
}
sub set_orderstatus {
my ($self,$order_id, $status) = @_;
- if ($status eq "fetched") { $status = "processing"; }
- if ($status eq "completed") { $status = "completed"; }
+ # if ($status eq "fetched") { $status = "processing"; }
+ # if ($status eq "processing") { $status = "completed"; }
my %new_status = (status => $status);
my $status_json = SL::JSON::to_json( \%new_status);
my $answer = $self->send_request("orders/$order_id", $status_json, "put");
my %return;
if($answer->is_success && $type eq 'application/json'){
my $data_json = $answer->content;
- #$main::lxdebug->dump(0, "TST: WooCommerce send_request header ", $answer->header( 'Link'));
my $json = SL::JSON::decode_json($data_json);
%return = (
success => 1,
data => $json,
- total_pages => $answer->header( 'X-WP-TotalPages'),
- total_elements => $answer->header( 'X-WP-Total'),
);
}else{
%return = (