mercator_mesonic 0.0.1 → 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,6 +3,12 @@ module MercatorMesonic
3
3
 
4
4
  self.table_name = "T026"
5
5
  self.primary_key = "c000"
6
+ attr_accessible :c000, :c003, :c004, :c005, :c006, :c007, :c008, :c009, :c010, :c011, :c012, :c013, :c014,
7
+ :c015, :c016, :c018, :c019, :c020, :c021, :c022, :c023, :c024, :c025, :c026, :c027, :c031,
8
+ :c032, :c033, :c034, :c035, :c042, :c044, :c045, :c046, :c047, :c048, :c052, :c054, :c055,
9
+ :c056, :c057, :c058, :c059, :c060, :c061, :c062, :c063, :c068, :c070, :c071, :c072, :c073,
10
+ :c074, :c075, :c077, :c078, :c081, :c082, :c083, :c085, :c086, :c087, :c088, :c091, :c092,
11
+ :c098, :c099, :c100, :c101, :c104, :C106, :C107, :C108, :C109, :mesocomp, :mesoyear, :mesoprim
6
12
 
7
13
  belongs_to :inventory, :foreign_key => "C003"
8
14
 
@@ -12,20 +18,23 @@ module MercatorMesonic
12
18
  # --- Class Methods --- #
13
19
 
14
20
  def self.initialize_mesonic(mesonic_order: nil, lineitem: nil, customer: nil, index: nil)
15
- id = mesonic_order.C000 + "-" + "%06d" % (index + 1 )
21
+ id = mesonic_order.c000 + "-" + "%06d" % (index + 1 )
22
+ product = lineitem.product
23
+ inventory = product.determine_inventory(amount: lineitem.amount)
24
+
16
25
  self.new(c000: id,
17
- c003: lineitem.inventory.article_number,
18
- c004: lineitem.inventory.Bezeichnung,
19
- c005: lineitem.menge, # menge bestellt
20
- c006: lineitem.menge, # menge geliefert
21
- c007: lineitem.einzelpreis, # einzelpreis
22
- c008: 0, # zeilenrabatt 1 und 2
26
+ c003: lineitem.product_number,
27
+ c004: lineitem.description_de,
28
+ c005: lineitem.amount, # menge bestellt
29
+ c006: lineitem.amount, # menge geliefert
30
+ c007: lineitem.product_price, # einzelpreis
31
+ c008: 0, # zeilenrabatt 1 und 2 #FIXME lineitem.discount_abs ?
23
32
  c009: 4002, # erlöskonto
24
- c010: lineitem.inventory.Steuersatzzeile, # umsatzsteuer prozentsatz #FIXME
33
+ c010: inventory.erp_vatline, # umsatzsteuer prozentsatz -> Steuersatzzeile
25
34
  c011: 1, # statistikkennzeichen
26
- c012: lineitem.inventory.ArtGruppe, # artikelgruppe #FIXME
35
+ c012: inventory.erp_article_group, # artikelgruppe
27
36
  c013: 0, # liefertage
28
- c014: lineitem.inventory.Provisionscode, # provisionscode #FIXME
37
+ c014: inventory.erp_provision_code, # provisionscode
29
38
  c015: nil, # colli
30
39
  c016: 0, # menge bereits geliefert
31
40
  c018: 0, # faktor 1 nach formeleingabe
@@ -38,10 +47,10 @@ module MercatorMesonic
38
47
  c025: mesonic_order.c027, # lieferdatum
39
48
  c026: 400, # kostenstelle
40
49
  c027: 0, # lieferwoche
41
- c031: lineitem.gesamtwert, # gesamtwert #FIXME
50
+ c031: lineitem.value, # gesamtwert
42
51
  c032: 0, # positionslevel
43
52
  c033: nil, # positionsnummer text
44
- c034: lineitem.inventory.Gewicht, # gewicht #FIXME
53
+ c034: inventory.weight, # gewicht
45
54
  c035: 0, # einstandspreis KZ
46
55
  c042: 1, # datentyp
47
56
  c044: mesonic_order.c021, # kontonummer
@@ -51,8 +60,8 @@ module MercatorMesonic
51
60
  c048: mesonic_order.c027.year, # lieferjahr
52
61
  c052: 0, # stat. wert
53
62
  c054: 0, # bewertungspreis editieren
54
- c055: lineitem.inventory.Auspraegungsflag, #FIXME
55
- c056: customer.erp_account_nr, # interessentenkontonummer
63
+ c055: inventory.erp_characteristic_flag, #Ausprägungsflag
64
+ c056: customer.mesonic_account_number, # interessentenkontonummer
56
65
  c057: 0, # lagerbestand ändern J/N
57
66
  c058: 0, # key für dispozeile
58
67
  c059: 0, # zeilennummer d kundenauftrags
@@ -71,7 +80,7 @@ module MercatorMesonic
71
80
  c078: index + 1, # zeilennummer (intern)
72
81
  c081: 0, # nummer des kontraktpreises
73
82
  c082: 0, # menge 2
74
- c083: lineitem.inventory.Steuersatzzeile * 10, #FIXME
83
+ c083: lineitem.vat, # Steuersatz in Prozent
75
84
  c085: 2, # exim durchgeführt änderungen
76
85
  c086: 0, # EURO einstandspreis
77
86
  c087: 0, # bnk-prozent
@@ -85,17 +94,11 @@ module MercatorMesonic
85
94
  c104: 0,
86
95
  mesocomp: AktMandant.mesocomp,
87
96
  mesoyear: AktMandant.mesoyear,
88
- mesoprim: id + "-" + AktMandant.mesocomp + "-" + AktMandant.mesoyear,
97
+ mesoprim: [id, AktMandant.mesocomp, AktMandant.mesoyear].join("-"),
89
98
  C106: "",
90
99
  C107: 0,
91
100
  C108: "",
92
101
  C109: 0 )
93
102
  end
94
-
95
- # --- Instance Methods --- #
96
-
97
- def readonly? # prevents unintentional changes
98
- true
99
- end
100
103
  end
101
104
  end
@@ -6,7 +6,7 @@ module MercatorMesonic
6
6
 
7
7
  scope :mesoyear, -> { where(mesoyear: AktMandant.mesoyear) }
8
8
  scope :mesocomp, -> { where(mesocomp: AktMandant.mesocomp) }
9
- default_scope { mesocomp.mesoyear.where(c002: 3).pluck(:c002, :c001, :c003, :c013) }
9
+ default_scope { mesocomp.mesoyear.where(c002: 3) }
10
10
 
11
11
  alias_attribute :price_column, :c013
12
12
 
@@ -36,12 +36,12 @@ module MercatorMesonic
36
36
  # find regular price
37
37
  scope :regular, -> { where(c001: "1") }
38
38
 
39
+ # --- Instance Methods --- #
40
+
39
41
  def price
40
- self.send( self.class.price_column )
42
+ self.c013
41
43
  end
42
44
 
43
- # --- Instance Methods --- #
44
-
45
45
  def readonly? # prevents unintentional changes
46
46
  true
47
47
  end
@@ -4,6 +4,9 @@ module MercatorMesonic
4
4
  self.table_name = "WEBARTIKEL"
5
5
  self.primary_key = "Artikelnummer"
6
6
 
7
+ has_many :mesonic_prices, :class_name => "Price",
8
+ :foreign_key => "c000", :primary_key => "Artikelnummer"
9
+
7
10
  # --- Class Methods --- #
8
11
 
9
12
  def self.import(update: "changed")
@@ -18,10 +21,18 @@ module MercatorMesonic
18
21
  @webartikel = Webartikel.all
19
22
  end
20
23
 
24
+ amount = @webartikel.count
25
+ index = 0
21
26
  if @webartikel.any?
22
27
  @webartikel.group_by{|webartikel| webartikel.Artikelnummer }.each do |artikelnummer, artikel|
28
+ index = index + 1
23
29
 
24
- Inventory.where(number: artikelnummer).destroy_all # This also deletes the prices!
30
+ @old_inventories = Inventory.where(number: artikelnummer)
31
+ if ( @old_inventories.destroy_all if @old_inventories )# This also deletes the prices!
32
+ ::JobLogger.info("Inventories deleted for Product " + artikelnummer)
33
+ else
34
+ ::JobLogger.error("Deleting Inventory failed: " + @old_inventories.errors.first)
35
+ end
25
36
 
26
37
  artikel.each do |webartikel|
27
38
  @product = Product.where(number: webartikel.Artikelnummer).first
@@ -32,8 +43,11 @@ module MercatorMesonic
32
43
  @product.categorizations.where(category_id: @discounts.id).destroy_all
33
44
  @product.categorizations.where(category_id: @topsellers.id).destroy_all
34
45
  if @product.lifecycle.can_reactivate?(User.where(administrator: true).first)
35
- @product.lifecycle.reactivate!(User.where(administrator: true).first)
36
- puts @product.number + " reactivated"
46
+ if @product.lifecycle.reactivate!(User.where(administrator: true).first)
47
+ ::JobLogger.info("Product " + @product.number + " reactivated.")
48
+ else
49
+ ::JobLogger.error("Product " + @product.number + " could not be reactivated!")
50
+ end
37
51
  end
38
52
  else
39
53
  @product = Product.create_in_auto(number: webartikel.Artikelnummer,
@@ -41,7 +55,7 @@ module MercatorMesonic
41
55
  description: webartikel.comment)
42
56
  end
43
57
 
44
- webartikel.Zusatzfeld5 ? delivery_time = webartikel.Zusatzfeld5 : delivery_time = "Auf Anfrage"
58
+ delivery_time = webartikel.Zusatzfeld5 ? webartikel.Zusatzfeld5 : I18n.t("mercator.on_request")
45
59
 
46
60
  @inventory = Inventory.new(product_id: @product.id,
47
61
  number: webartikel.Artikelnummer,
@@ -51,45 +65,60 @@ module MercatorMesonic
51
65
  charge: webartikel.LfdChargennr,
52
66
  unit: "Stk.",
53
67
  delivery_time: delivery_time,
54
- amount: 9999,
55
- erp_updated_at: webartikel.letzteAend)
56
-
57
- if webartikel.Kennzeichen = "T"
68
+ amount: 0,
69
+ erp_updated_at: webartikel.letzteAend,
70
+ erp_vatline: webartikel.Steuersatzzeile,
71
+ erp_article_group: webartikel.ArtGruppe,
72
+ erp_provision_code: webartikel.Provisionscode,
73
+ erp_characteristic_flag: webartikel.Auspraegungsflag,
74
+ infinite: true,
75
+ just_imported: true,
76
+ alternative_number: webartikel.AltArtNr1)
77
+
78
+ if ( webartikel.Kennzeichen == "T" ) &&
79
+ ( webartikel.Artikelnummer != Constant.find_by_key("shipping_cost_article").value )
58
80
  @product.topseller = true
59
81
  position = 1
60
82
  position = @topsellers.categorizations.maximum(:position) + 1 if @topsellers.categorizations.any?
61
83
  @product.categorizations.new(category_id: @topsellers.id, position: position)
84
+ else
85
+ @product.categorizations.where(category_id: @topsellers.id).destroy_all
62
86
  end
63
87
 
64
- if webartikel.Kennzeichen = "N"
88
+ if ( webartikel.Kennzeichen == "N" ) &&
89
+ ( webartikel.Artikelnummer != Constant.find_by_key("shipping_cost_article").value )
65
90
  @product.novelty = true
66
91
  position = 1
67
92
  position = @novelties.categorizations.maximum(:position) + 1 if @novelties.categorizations.any?
68
93
  @product.categorizations.new(category_id: @novelties.id, position: position)
94
+ else
95
+ @product.categorizations.where(category_id: @novelties.id).destroy_all
69
96
  end
70
97
 
71
- if webartikel.PreisdatumVON && webartikel.PreisdatumVON <= Time.now &&
72
- webartikel.PreisdatumBIS && webartikel.PreisdatumBIS >= Time.now
98
+ if webartikel.PreisdatumVON && ( webartikel.PreisdatumVON <= Time.now ) &&
99
+ webartikel.PreisdatumBIS && ( webartikel.PreisdatumBIS >= Time.now )
73
100
  position = 1
74
101
  position = @discounts.categorizations.maximum(:position) + 1 if @discounts.categorizations.any?
75
102
  @product.categorizations.new(category_id: @discounts.id, position: position)
103
+ else
104
+ @product.categorizations.where(category_id: @discounts.id).destroy_all
76
105
  end
77
106
 
78
107
  if @inventory.save
79
- print "I"
108
+ ::JobLogger.info("Inventory " + @inventory.number + " saved.")
80
109
  else
81
- puts @inventory.errors.first.to_s
110
+ ::JobLogger.error("Saving Inventory failed: " + @inventory.errors.first.to_s)
82
111
  end
83
112
 
84
113
  # --- Price-Handling --- #
85
114
  @price = Price.new(value: webartikel.Preis,
86
115
  scale_from: webartikel.AbMenge,
87
116
  scale_to: 9999,
88
- vat: 20,
117
+ vat: webartikel.Steuersatzzeile * 10,
89
118
  inventory_id: @inventory.id)
90
119
 
91
- if webartikel.PreisdatumVON && webartikel.PreisdatumVON <= Time.now &&
92
- webartikel.PreisdatumBIS && webartikel.PreisdatumBIS >= Time.now
120
+ if webartikel.PreisdatumVON && ( webartikel.PreisdatumVON <= Time.now ) &&
121
+ webartikel.PreisdatumBIS && ( webartikel.PreisdatumBIS >= Time.now )
93
122
  @price.promotion = true
94
123
  @price.valid_from = webartikel.PreisdatumVON
95
124
  @price.valid_to = webartikel.PreisdatumBIS
@@ -99,9 +128,9 @@ module MercatorMesonic
99
128
  end
100
129
 
101
130
  if @price.save
102
- print "$"
131
+ ::JobLogger.info("Price for Inventory " + @price.inventory_id.to_s + " saved.")
103
132
  else
104
- puts @price.errors.first.to_s
133
+ ::JobLogger.error("Saving Price failed: " + @price.errors.first.to_s)
105
134
  end
106
135
 
107
136
  # --- recommendations-Handling --- #
@@ -112,15 +141,64 @@ module MercatorMesonic
112
141
  end
113
142
 
114
143
  if @product.save
115
- print "P"
144
+ ::JobLogger.info("Recommendation for Product " + @product.number + " saved.")
116
145
  else
117
- puts @inventory.errors.first.to_s
146
+ ::JobLogger.error("Saving Recommendation failed: " + @product.errors.first.to_s)
118
147
  end
119
148
  end
149
+ ::JobLogger.info("----- Finished: " + artikelnummer.to_s + " (" + index.to_s + "/" + amount.to_s + ") -----")
120
150
  end
121
151
  else
122
- puts "No new entries in WEBARTIKEL View"
152
+ ::JobLogger.info("No new entries in WEBARTIKEL View, nothing updated.")
153
+ end
154
+
155
+ self.remove_orphans(only_old: true)
156
+
157
+ ::JobLogger.info("Deprecating products ... ")
158
+ ::Product.deprecate
159
+ end
160
+
161
+
162
+ def self.remove_orphans(only_old: false)
163
+ ::JobLogger.info("Removing orphans ...")
164
+ if only_old
165
+ @inventories = Inventory.where(just_imported: [false, nil])
166
+ else
167
+ @inventories = Inventory.all
168
+ end
169
+ @inventories.each do |inventory|
170
+ if MercatorMesonic::Webartikel.where(Artikelnummer: inventory.number).count == 0
171
+ if inventory.destroy
172
+ ::JobLogger.info("Deleted Inventory " + inventory.number.to_s)
173
+ else
174
+ ::JobLogger.info("Deleting Inventory failed: " + inventory.errors.first)
175
+ end
176
+ else
177
+ ::JobLogger.info("Inventory " + inventory.number.to_s + " still present in MercatorMesonic::Webartikel.")
178
+ end
179
+ end
180
+ ::JobLogger.info("Resetting new inventories ...")
181
+ Inventory.where(just_imported: true).each do |inventory|
182
+ inventory.update_attributes(just_imported: false)
123
183
  end
184
+ ::JobLogger.info("... completed, removing orphans finished.")
185
+ end
186
+
187
+
188
+ def self.test_connection
189
+ [1,2,3].each do |attempt|
190
+ begin
191
+ self.count # that actually tries to establish a connection
192
+ ::JobLogger.info("Connection to Mesonic database established successfully.")
193
+ puts "further logging goes to Joblog: /log/RAILS_ENV_job.log ..."
194
+ return true
195
+ rescue
196
+ ::JobLogger.fatal("Connection to Mesonic database could not be established! (attempt no." + attempt.to_s + ")")
197
+ puts "FATAL ERROR: Connection to Mesonic database could not be established! (attempt no." + attempt.to_s + ")"
198
+ end
199
+ end
200
+
201
+ return false
124
202
  end
125
203
 
126
204
  # --- Instance Methods --- #
@@ -0,0 +1,45 @@
1
+ module OrderExtensions
2
+
3
+ # --- Instance Methods --- #
4
+ def mesonic_payment_id
5
+ {"cash_payment" => '1002', "atm_payment" => '1003', "pre_payment" => '1010', "e_payment" => '1011'}[self.billing_method]
6
+ # further Mesonic ids Nachnahme => '1001'
7
+ end
8
+
9
+ def mesonic_payment_id2
10
+ {"1002" => "17", "1003" => "17", "1010" => "19", "1011" => "25" }[self.mesonic_payment_id]
11
+ # "1001" => "17"
12
+ end
13
+
14
+ def mesonic_shipping_id
15
+ {"parcel_service_shipment" => '1', "pickup_shipment" => '2'}[self.shipping_method]
16
+ end
17
+
18
+ def push_to_mesonic
19
+ mesonic_order = MercatorMesonic::Order.initialize_mesonic(order: self)
20
+ mesonic_order_items = []
21
+ self.lineitems.each_with_index do |lineitem, index|
22
+ mesonic_order_items << MercatorMesonic::OrderItem.initialize_mesonic(mesonic_order: mesonic_order, lineitem: lineitem,
23
+ customer: self.user, index: index)
24
+ end
25
+
26
+ ::JobLogger.debug(mesonic_order)
27
+ mesonic_order_items.each do |mesonic_order_item|
28
+ ::JobLogger.debug(mesonic_order_item)
29
+ end
30
+
31
+ save_return_value = Order.transaction do
32
+ mesonic_order.save
33
+ mesonic_order_items.collect(&:save)
34
+ end
35
+
36
+ if save_return_value
37
+ self.update(erp_customer_number: self.user.erp_account_nr,
38
+ erp_billing_number: mesonic_order.c021,
39
+ erp_order_number: mesonic_order.c022)
40
+ OrderMailer.order_confirmation(order: self)
41
+ else
42
+ raise "Error! Order could not be pushed to mesonic!"
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,89 @@
1
+ module UserExtensions
2
+
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ attr_accessible :mesonic_kontakte_stamm, :mesonic_kontenstamm, :mesonic_kontenstamm_fakt,
7
+ :mesonic_kontenstamm_fibu, :mesonic_kontenstamm_adresse
8
+
9
+ belongs_to :mesonic_kontakte_stamm, class_name: "MercatorMesonic::KontakteStamm",
10
+ foreign_key: :erp_contact_nr, primary_key: :mesoprim
11
+
12
+ belongs_to :mesonic_kontenstamm, class_name: "MercatorMesonic::Kontenstamm",
13
+ foreign_key: :erp_account_nr, primary_key: :mesoprim
14
+ accepts_nested_attributes_for :mesonic_kontenstamm, allow_destroy: false
15
+
16
+ belongs_to :mesonic_kontenstamm_fakt, class_name: "MercatorMesonic::KontenstammFakt",
17
+ foreign_key: :erp_account_nr, primary_key: :mesoprim
18
+ accepts_nested_attributes_for :mesonic_kontenstamm_fakt, allow_destroy: false
19
+
20
+ belongs_to :mesonic_kontenstamm_fibu, class_name: "MercatorMesonic::KontenstammFibu",
21
+ foreign_key: :erp_account_nr, primary_key: :mesoprim
22
+ accepts_nested_attributes_for :mesonic_kontenstamm_fibu, allow_destroy: false
23
+
24
+ belongs_to :mesonic_kontenstamm_adresse, class_name: "MercatorMesonic::KontenstammAdresse",
25
+ foreign_key: :erp_account_nr, primary_key: :mesoprim
26
+ accepts_nested_attributes_for :mesonic_kontenstamm_adresse, allow_destroy: false
27
+
28
+ def self.update_erp_account_nrs
29
+ erp_users = User.where.not(erp_contact_nr: nil)
30
+ erp_users.each {|erp_user| erp_user.update_erp_account_nr}
31
+ end
32
+ end
33
+
34
+ # --- Instance Methods --- #
35
+
36
+ def push_to_mesonic
37
+ @timestamp = Time.now
38
+
39
+ @kontonummer = MercatorMesonic::Kontenstamm.next_kontonummer
40
+ @kontaktenummer = MercatorMesonic::KontakteStamm.next_kontaktenummer
41
+
42
+ @mesonic_kontakte_stamm = MercatorMesonic::KontakteStamm.initialize_mesonic(user: self, kontonummer: @kontonummer, kontaktenummer: @kontaktenummer)
43
+ @mesonic_kontenstamm = MercatorMesonic::Kontenstamm.initialize_mesonic(user: self, kontonummer: @kontonummer, timestamp: @timestamp)
44
+ @mesonic_kontenstamm_fakt = MercatorMesonic::KontenstammFakt.initialize_mesonic(kontonummer: @kontonummer, email: self.email_address)
45
+ @mesonic_kontenstamm_fibu = MercatorMesonic::KontenstammFibu.initialize_mesonic(kontonummer: @kontonummer)
46
+ @mesonic_kontenstamm_adresse = MercatorMesonic::KontenstammAdresse.initialize_mesonic(billing_address: self.billing_addresses.first, kontonummer: @kontonummer)
47
+
48
+ if [@mesonic_kontakte_stamm, @mesonic_kontenstamm, @mesonic_kontenstamm_adresse,
49
+ @mesonic_kontenstamm_fibu, @mesonic_kontenstamm_fakt ].collect(&:valid?).all?
50
+
51
+ [@mesonic_kontakte_stamm, @mesonic_kontenstamm, @mesonic_kontenstamm_adresse,
52
+ @mesonic_kontenstamm_fibu, @mesonic_kontenstamm_fakt ].collect(&:save).all?
53
+
54
+ end
55
+
56
+ self.update(erp_account_nr: User.mesoprim(number: @kontonummer),
57
+ erp_contact_nr: User.mesoprim(number: @kontaktenummer) )
58
+ end
59
+
60
+ def update_mesonic(billing_address: self.billing_addresses.first)
61
+ mesonic_kontenstamm_adresse = MercatorMesonic::KontenstammAdresse.where(mesoprim: self.erp_account_nr).first
62
+
63
+ mesonic_kontenstamm_adresse.update(c050: billing_address.street,
64
+ c051: billing_address.postalcode,
65
+ c052: billing_address.city,
66
+ c053: billing_address.c_o,
67
+ c123: billing_address.country,
68
+ c181: billing_address.name.split(/\s/).last,
69
+ c116: billing_address.email_address.to_s)
70
+ end
71
+
72
+ def mesonic_account_number
73
+ "%06d" % self.erp_account_nr[0..-11] # ...it is actually a string and may contain 1I for potential buyers
74
+ end
75
+
76
+ def update_erp_account_nr
77
+ # We want to fix the local database entry for erp_account_nr if someone changed the Account on mesonic side,
78
+ # e.g. if the potential customer ('Interessent') was changed to an actual customer accout.
79
+ if self.erp_contact_nr && !self.mesonic_kontenstamm && self.mesonic_kontakte_stamm
80
+ mesonic_kontenstamm = MercatorMesonic::Kontenstamm.where(c002: self.mesonic_kontakte_stamm.c039).first
81
+
82
+ if self.update(erp_account_nr: mesonic_kontenstamm.mesoprim)
83
+ ::JobLogger.info("Updated user " + self.id.to_s + "'s erp account number to " + self.erp_account_nr)
84
+ else
85
+ ::JobLogger.error("Error updating user" + self.id.to_s + "'s erp account number")
86
+ end
87
+ end
88
+ end
89
+ end